diff --git a/README.md b/README.md index e8198742..bdd9d0ab 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ In this stage we will use the console the manually run the ElectricEye ECS task. 3. Select **Run task**, in the next screen select the hyperlink in the **Task** column and select the **Logs** tab to view the result of the logs. **Note** logs coming to this screen may be delayed, and you may have several auditors report failures due to the lack of in-scope resources. ## Supported Services and Checks -These are the following services and checks perform by each Auditor. There are currently **212** checks supported across **65** AWS services / components using **47** Auditors. There are currently **62** supported response and remediation Playbooks with coverage across **32** AWS services / components supported by [ElectricEye-Response](https://github.com/jonrau1/ElectricEye/blob/master/add-ons/electriceye-response). +These are the following services and checks perform by each Auditor. There are currently **214** checks supported across **66** AWS services / components using **48** Auditors. There are currently **62** supported response and remediation Playbooks with coverage across **32** AWS services / components supported by [ElectricEye-Response](https://github.com/jonrau1/ElectricEye/blob/master/add-ons/electriceye-response). **Regarding Shield Advanced checks:** You must be subscribed to Shield Advanced, be on Business/Enterprise Support and be in us-east-1 to perform all checks. The Shield Adv API only lives in us-east-1, and to have the DRT look at your account you need Biz/Ent support, hence the pre-reqs. @@ -445,6 +445,8 @@ These are the following services and checks perform by each Auditor. There are c | AWS_IAM_Auditor.py | IAM User | Do users have managed policies attached | | AWS_IAM_Auditor.py | Password policy (Account) | Does the IAM password policy meet or exceed
AWS CIS Foundations Benchmark standards | | AWS_IAM_Auditor.py | Server certs (Account) | Are they any Server certificates stored by IAM | +| AWS_KMS_Auditor.py | KMS key | Is key rotation enabled | +| AWS_KMS_Auditor.py | KMS key | Does the key allow public access | | AWS_Lambda_Auditor.py | Lambda function | Has function been used or updated in the last
30 days | | AWS_License_Manager_Auditor | License Manager configuration | Do LM configurations enforce a hard limit on
license consumption | | AWS_Secrets_Manager_Auditor.py | Secrets Manager secret | Is the secret over 90 days old | diff --git a/audit_controller.py b/audit_controller.py deleted file mode 100644 index 479be80b..00000000 --- a/audit_controller.py +++ /dev/null @@ -1,141 +0,0 @@ -# This file is part of ElectricEye. - -# ElectricEye is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# ElectricEye is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along with ElectricEye. -# If not, see https://github.com/jonrau1/ElectricEye/blob/master/LICENSE. - -import csv -import json -import getopt -import importlib -import os -import sys -import boto3 -from time import sleep -from functools import reduce -from auditors.Auditor import Auditor, AuditorCollection - - -# Return nested dictionary values by passing in dictionary and keys separated by "." -def deep_get(dictionary, keys): - return reduce( - lambda d, key: d.get(key) if isinstance(d, dict) else None, - keys.split("."), - dictionary, - ) - - -def csv_output(output_file, findings): - csv_columns = [ - {"name": "Id", "path": "Id"}, - {"name": "Title", "path": "Title"}, - {"name": "ProductArn", "path": "ProductArn"}, - {"name": "AwsAccountId", "path": "AwsAccountId"}, - {"name": "Severity", "path": "Severity.Label"}, - {"name": "Confidence", "path": "Confidence"}, - {"name": "Description", "path": "Description"}, - {"name": "RecordState", "path": "RecordState"}, - {"name": "Compliance Status", "path": "Compliance.Status"}, - { - "name": "Remediation Recommendation", - "path": "Remediation.Recommendation.Text", - }, - { - "name": "Remediation Recommendation Link", - "path": "Remediation.Recommendation.Url", - }, - ] - csv_file = output_file - try: - with open(csv_file, "w") as csvfile: - writer = csv.writer(csvfile, dialect="excel") - writer.writerow(item["name"] for item in csv_columns) - for finding in findings: - row_data = [] - for column_dict in csv_columns: - row_data.append(deep_get(finding, column_dict["path"])) - writer.writerow(row_data) - except IOError: - print("I/O error") - - -def main(argv): - findings_list = [] # used if --output is specified - profile_name = "" - auditor_name = "" - check_name = "" - output = False - output_file = "" - help_text = "audit_controller.py [-p -a -c -o ]" - try: - opts, args = getopt.getopt( - argv, "ho:p:a:c:", ["help", "output=", "profile=", "auditor=", "check="] - ) - except getopt.GetoptError: - print(help_text) - sys.exit(2) - for opt, arg in opts: - if opt in ("-h", "--help"): - print(help_text) - sys.exit(2) - if opt in ("-o", "--output"): - output = True - output_file = arg - if opt in ("-p", "--profile"): - profile_name = arg - if opt in ("-a", "--auditor"): - auditor_name = arg - if opt in ("-c", "--check"): - check_name = arg - if profile_name: - boto3.setup_default_session(profile_name=profile_name) - - # load all Auditor plugins in the "auditors" directory - auditors = AuditorCollection("auditors") - securityhub = boto3.client("securityhub") - - for plugin in auditors.plugins: - try: - # if user specifies a specific auditor on CLI, skip all other auditors - if auditor_name: - if "auditors." + auditor_name != plugin.get("auditor"): - continue - check = plugin.get("check") - # if user specifies a specific check on CLI, skip all other checks - if check_name: - if check.name != check_name: - continue - print(f"Executing check: {check.name}") - for finding in check.execute(): - # It would be possible to collect these fidnings and batch them up before sending. - # This current implementation has the advantage of a small memory footprint, but - # could be a slight performance improvement to batch and make one securityhub - # call per check. - response = securityhub.batch_import_findings(Findings=[finding]) - # if -o arg, add finding to findings list to be used to generate csv output - if output: - findings_list.append(finding) - sleep(0.5) # a hack to avoid api limit by sleeping between checks - except Exception as e: - print(f"Error running plugin {plugin.get('check').name} with exception {e}") - if output: - print(f"Writing {len(findings_list)} findings to {output_file}") - csv_output(output_file, findings_list) - - print("Done") - - -if __name__ == "__main__": - # this is for local testing where the AWS_REGION is not liekly set - if not os.environ.get("AWS_REGION", None): - os.environ["AWS_REGION"] = "us-east-1" - main(sys.argv[1:]) diff --git a/cloudformation/ElectricEye_CFN.yaml b/cloudformation/ElectricEye_CFN.yaml index 98b41a4d..224f28dd 100644 --- a/cloudformation/ElectricEye_CFN.yaml +++ b/cloudformation/ElectricEye_CFN.yaml @@ -252,6 +252,10 @@ Resources: - kinesis:ListStreams - kms:Decrypt - kms:DescribeKey + - kms:GetKeyPolicy + - kms:GetKeyRotationStatus + - kms:ListAliases + - kms:ListKeys - lambda:ListFunctions - license-manager:GetLicenseConfiguration - license-manager:ListLicenseConfigurations diff --git a/eeauditor/auditors/AWS_KMS_Auditor.py b/eeauditor/auditors/AWS_KMS_Auditor.py new file mode 100644 index 00000000..a705838a --- /dev/null +++ b/eeauditor/auditors/AWS_KMS_Auditor.py @@ -0,0 +1,245 @@ +# This file is part of ElectricEye. + +# ElectricEye is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# ElectricEye is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License along with ElectricEye. +# If not, see https://github.com/jonrau1/ElectricEye/blob/master/LICENSE. + +import boto3 +import datetime +import json +import os +from auditors.Auditor import Auditor + +# import boto3 clients +sts = boto3.client("sts") +kms = boto3.client("kms") + + +class KMSKeyRotationCheck(Auditor): + def execute(self): + awsAccountId = sts.get_caller_identity()["Account"] + awsRegion = os.environ["AWS_REGION"] + keys = kms.list_keys() + my_keys = keys["Keys"] + iso8601Time = datetime.datetime.now(datetime.timezone.utc).isoformat() + for key in my_keys: + keyid = key["KeyId"] + keyarn = key["KeyArn"] + key_rotation = kms.get_key_rotation_status(KeyId=keyid) + if key_rotation["KeyRotationEnabled"] == True: + finding = { + "SchemaVersion": "2018-10-08", + "Id": keyarn + "/kms-key-rotation-check", + "ProductArn": "arn:aws:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": keyarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "INFORMATIONAL"}, + "Confidence": 99, + "Title": "[KMS.1] KMS keys should have key rotation enabled", + "Description": "KMS Key " + + keyid + + " does have key rotation enabled.", + "Remediation": { + "Recommendation": { + "Text": "For more information on KMS key rotation refer to the AWS KMS Developer Guide on Rotating Keys", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsKey", + "Id": keyarn, + "Partition": "aws", + "Region": awsRegion, + "Details": {"AwsKmsKey": {"KeyId": keyid}}, + } + ], + "Compliance": {"Status": "PASSED"}, + "Workflow": {"Status": "RESOLVED"}, + "RecordState": "ARCHIVED", + } + yield finding + else: + finding = { + "SchemaVersion": "2018-10-08", + "Id": keyarn + "/kms-key-rotation-check", + "ProductArn": "arn:aws:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": keyarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "MEDIUM"}, + "Confidence": 99, + "Title": "[KMS.1] KMS keys should have key rotation enabled", + "Description": "KMS key " + + keyid + + " does not have key rotation enabled.", + "Remediation": { + "Recommendation": { + "Text": "For more information on KMS key rotation refer to the AWS KMS Developer Guide on Rotating Keys", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsKey", + "Id": keyarn, + "Partition": "aws", + "Region": awsRegion, + "Details": {"AwsKmsKey": {"KeyId": keyid}}, + } + ], + "Compliance": {"Status": "FAILED"}, + "Workflow": {"Status": "NEW"}, + "RecordState": "ACTIVE", + } + yield finding + + +class KMSKeyExposedCheck(Auditor): + def execute(self): + awsAccountId = sts.get_caller_identity()["Account"] + awsRegion = os.environ["AWS_REGION"] + response = kms.list_aliases() + aliasList = response["Aliases"] + iso8601Time = datetime.datetime.now(datetime.timezone.utc).isoformat() + for alias in aliasList: + if "TargetKeyId" in alias: + aliasArn = alias["AliasArn"] + keyid = alias["TargetKeyId"] + policyString = kms.get_key_policy(KeyId=keyid, PolicyName="default") + fail = False + policy_json = policyString["Policy"] + policy = json.loads(policy_json) + for sid in policy["Statement"]: + access = sid["Principal"].get("AWS", None) + if access != "*" or (access == "*" and "Condition" in sid): + continue + else: + fail = True + break + if not fail: + finding = { + "SchemaVersion": "2018-10-08", + "Id": aliasArn + "/kms-key-exposed-check", + "ProductArn": "arn:aws:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": aliasArn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "INFORMATIONAL"}, + "Confidence": 75, # The Condition may not effectively limit access + "Title": "[KMS.2] KMS keys should not have public access", + "Description": "KMS key " + + keyid + + " does not have public access or limited by a Condition. Refer to the remediation instructions to review kms access policy", + "Remediation": { + "Recommendation": { + "Text": "For more information on AWS KMS key policies refer to Using key policies in AWS KMS section of the AWS KMS Developer Guide.", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsAlias", + "Id": aliasArn, + "Partition": "aws", + "Region": awsRegion, + } + ], + "Compliance": {"Status": "PASSED"}, + "Workflow": {"Status": "RESOLVED"}, + "RecordState": "ARCHIVED", + } + yield finding + else: + finding = { + "SchemaVersion": "2018-10-08", + "Id": aliasArn + "/kms-key-exposed-check", + "ProductArn": "arn:aws:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": aliasArn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "HIGH"}, + "Confidence": 99, + "Title": "[KMS.2] KMS keys should not have public access", + "Description": "KMS key " + + keyid + + " has public access. Refer to the remediation instructions to review kms access policy", + "Remediation": { + "Recommendation": { + "Text": "For more information on AWS KMS key policies refer to Using key policies in AWS KMS section of the AWS KMS Developer Guide.", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsAlias", + "Id": aliasArn, + "Partition": "aws", + "Region": awsRegion, + } + ], + "Compliance": {"Status": "FAILED"}, + "Workflow": {"Status": "NEW"}, + "RecordState": "ACTIVE", + } + yield finding diff --git a/eeauditor/auditors/aws/Amazon_SNS_Auditor.py b/eeauditor/auditors/aws/Amazon_SNS_Auditor.py index 4698aa13..ee0ad74f 100644 --- a/eeauditor/auditors/aws/Amazon_SNS_Auditor.py +++ b/eeauditor/auditors/aws/Amazon_SNS_Auditor.py @@ -304,7 +304,7 @@ def sns_public_access_check(cache: dict, awsAccountId: str, awsRegion: str) -> d fail = False # this results in one finding per topic instead of one finding per statement for sid in statement["Statement"]: - access = sid["Principal"].get("AWS") + access = sid["Principal"].get("AWS", None) if access != "*" or (access == "*" and "Condition" in sid): continue else: @@ -450,132 +450,138 @@ def sns_cross_account_check(cache: dict, awsAccountId: str, awsRegion: str) -> d response = sns.get_topic_attributes(TopicArn=topicarn) myPolicy_json = str(response["Attributes"]["Policy"]) myPolicy = json.loads(myPolicy_json) + fail = False for statement in myPolicy["Statement"]: - principal = statement["Principal"].get("AWS") - if principal[0] != "*": - if not principal[0].isdigit(): + principal = statement["Principal"].get("AWS", None) + if principal and principal != "*": + if not principal.isdigit(): + # This assumes if it is not a digit that it must be an arn. + # not sure if this is a safe assumption. principal = principal.split(":")[4] if principal == awsAccountId: - finding = { - "SchemaVersion": "2018-10-08", - "Id": topicarn + "/sns-cross-account-check", - "ProductArn": "arn:aws:securityhub:" - + awsRegion - + ":" - + awsAccountId - + ":product/" - + awsAccountId - + "/default", - "GeneratorId": topicarn, - "AwsAccountId": awsAccountId, - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure", - ], - "FirstObservedAt": iso8601Time, - "CreatedAt": iso8601Time, - "UpdatedAt": iso8601Time, - "Severity": {"Label": "INFORMATIONAL"}, - "Confidence": 99, - "Title": "[SNS.4] SNS topics should not allow cross-account access", - "Description": "SNS topic " - + topicName - + " does not have cross-account access.", - "Remediation": { - "Recommendation": { - "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", - "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", - } - }, - "ProductFields": {"Product Name": "ElectricEye"}, - "Resources": [ - { - "Type": "AwsSnsTopic", - "Id": topicarn, - "Partition": "aws", - "Region": awsRegion, - "Details": {"AwsSnsTopic": {"TopicName": topicName}}, - } - ], - "Compliance": { - "Status": "PASSED", - "RelatedRequirements": [ - "NIST CSF PR.AC-3", - "NIST SP 800-53 AC-1", - "NIST SP 800-53 AC-17", - "NIST SP 800-53 AC-19", - "NIST SP 800-53 AC-20", - "NIST SP 800-53 SC-15", - "AICPA TSC CC6.6", - "ISO 27001:2013 A.6.2.1", - "ISO 27001:2013 A.6.2.2", - "ISO 27001:2013 A.11.2.6", - "ISO 27001:2013 A.13.1.1", - "ISO 27001:2013 A.13.2.1", - ], - }, - "Workflow": {"Status": "RESOLVED"}, - "RecordState": "ARCHIVED", - } - yield finding + continue else: - finding = { - "SchemaVersion": "2018-10-08", - "Id": topicarn + "/sns-cross-account-check", - "ProductArn": "arn:aws:securityhub:" - + awsRegion - + ":" - + awsAccountId - + ":product/" - + awsAccountId - + "/default", - "GeneratorId": topicarn, - "AwsAccountId": awsAccountId, - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure", - ], - "FirstObservedAt": iso8601Time, - "CreatedAt": iso8601Time, - "UpdatedAt": iso8601Time, - "Severity": {"Label": "Low"}, - "Confidence": 99, - "Title": "[SNS.4] SNS topics should not allow cross-account access", - "Description": "SNS topic " + topicName + " has cross-account access.", - "Remediation": { - "Recommendation": { - "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", - "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", - } - }, - "ProductFields": {"Product Name": "ElectricEye"}, - "Resources": [ - { - "Type": "AwsSnsTopic", - "Id": topicarn, - "Partition": "aws", - "Region": awsRegion, - "Details": {"AwsSnsTopic": {"TopicName": topicName}}, - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF PR.AC-3", - "NIST SP 800-53 AC-1", - "NIST SP 800-53 AC-17", - "NIST SP 800-53 AC-19", - "NIST SP 800-53 AC-20", - "NIST SP 800-53 SC-15", - "AICPA TSC CC6.6", - "ISO 27001:2013 A.6.2.1", - "ISO 27001:2013 A.6.2.2", - "ISO 27001:2013 A.11.2.6", - "ISO 27001:2013 A.13.1.1", - "ISO 27001:2013 A.13.2.1", - ], - }, - "Workflow": {"Status": "NEW"}, - "RecordState": "ACTIVE", + fail = True + break + if not fail: + finding = { + "SchemaVersion": "2018-10-08", + "Id": topicarn + "/sns-cross-account-check", + "ProductArn": "arn:aws:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": topicarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "INFORMATIONAL"}, + "Confidence": 99, + "Title": "[SNS.4] SNS topics should not allow cross-account access", + "Description": "SNS topic " + topicName + " does not have cross-account access.", + "Remediation": { + "Recommendation": { + "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", + "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsSnsTopic", + "Id": topicarn, + "Partition": "aws", + "Region": awsRegion, + "Details": {"AwsSnsTopic": {"TopicName": topicName}}, + } + ], + "Compliance": { + "Status": "PASSED", + "RelatedRequirements": [ + "NIST CSF PR.AC-3", + "NIST SP 800-53 AC-1", + "NIST SP 800-53 AC-17", + "NIST SP 800-53 AC-19", + "NIST SP 800-53 AC-20", + "NIST SP 800-53 SC-15", + "AICPA TSC CC6.6", + "ISO 27001:2013 A.6.2.1", + "ISO 27001:2013 A.6.2.2", + "ISO 27001:2013 A.11.2.6", + "ISO 27001:2013 A.13.1.1", + "ISO 27001:2013 A.13.2.1", + ], + }, + "Workflow": {"Status": "RESOLVED"}, + "RecordState": "ARCHIVED", + } + yield finding + else: + finding = { + "SchemaVersion": "2018-10-08", + "Id": topicarn + "/sns-cross-account-check", + "ProductArn": "arn:aws:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": topicarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "Low"}, + "Confidence": 99, + "Title": "[SNS.4] SNS topics should not allow cross-account access", + "Description": "SNS topic " + topicName + " has cross-account access.", + "Remediation": { + "Recommendation": { + "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", + "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsSnsTopic", + "Id": topicarn, + "Partition": "aws", + "Region": awsRegion, + "Details": {"AwsSnsTopic": {"TopicName": topicName}}, } - yield finding + ], + "Compliance": { + "Status": "FAILED", + "RelatedRequirements": [ + "NIST CSF PR.AC-3", + "NIST SP 800-53 AC-1", + "NIST SP 800-53 AC-17", + "NIST SP 800-53 AC-19", + "NIST SP 800-53 AC-20", + "NIST SP 800-53 SC-15", + "AICPA TSC CC6.6", + "ISO 27001:2013 A.6.2.1", + "ISO 27001:2013 A.6.2.2", + "ISO 27001:2013 A.11.2.6", + "ISO 27001:2013 A.13.1.1", + "ISO 27001:2013 A.13.2.1", + ], + }, + "Workflow": {"Status": "NEW"}, + "RecordState": "ACTIVE", + } + yield finding diff --git a/findings.json b/findings.json deleted file mode 100644 index 72b34d08..00000000 --- a/findings.json +++ /dev/null @@ -1,2209 +0,0 @@ -{"Findings":[ -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:cacheMe/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:cacheMe", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function cacheMe has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:cacheMe", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:workflow-callback/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:workflow-callback", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function workflow-callback has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:workflow-callback", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverlessrepo-task-monit-dynamodbprocessstreampyt-1V5E6UO6SLJXB/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:serverlessrepo-task-monit-dynamodbprocessstreampyt-1V5E6UO6SLJXB", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function serverlessrepo-task-monit-dynamodbprocessstreampyt-1V5E6UO6SLJXB has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverlessrepo-task-monit-dynamodbprocessstreampyt-1V5E6UO6SLJXB", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:test_async/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:test_async", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function test_async has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:test_async", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:rules_engine/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:rules_engine", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function rules_engine has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:rules_engine", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:kinesis_event_writer/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:kinesis_event_writer", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function kinesis_event_writer has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:kinesis_event_writer", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-result_runner/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-result_runner", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function serverless-flask-dev-result_runner has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-result_runner", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:lambda-runner/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:lambda-runner", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function lambda-runner has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:lambda-runner", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-engine/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-engine", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function serverless-flask-dev-engine has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-engine", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:rock-paper-scissors/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:rock-paper-scissors", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function rock-paper-scissors has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:rock-paper-scissors", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:toSlack-dev-to_slack/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:toSlack-dev-to_slack", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function toSlack-dev-to_slack has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:toSlack-dev-to_slack", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-lambda_runner/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-lambda_runner", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function serverless-flask-dev-lambda_runner has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-lambda_runner", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:add/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:add", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "INFORMATIONAL" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function add has been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:add", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "PASSED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "RESOLVED" - }, - "RecordState": "ARCHIVED" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:task-writer/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:task-writer", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function task-writer has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:task-writer", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:reservedCurrency/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:reservedCurrency", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function reservedCurrency has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:reservedCurrency", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:high-low/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:high-low", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function high-low has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:high-low", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:stock-picker-dev-stock-picker/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:stock-picker-dev-stock-picker", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "INFORMATIONAL" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function stock-picker-dev-stock-picker has been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:stock-picker-dev-stock-picker", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "PASSED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "RESOLVED" - }, - "RecordState": "ARCHIVED" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:workflow-dev-app/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:workflow-dev-app", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function workflow-dev-app has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:workflow-dev-app", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:my-first-test/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:my-first-test", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "INFORMATIONAL" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function my-first-test has been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:my-first-test", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "PASSED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "RESOLVED" - }, - "RecordState": "ARCHIVED" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:reddit-slackbot-dev-runner/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:reddit-slackbot-dev-runner", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "INFORMATIONAL" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function reddit-slackbot-dev-runner has been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:reddit-slackbot-dev-runner", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "PASSED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "RESOLVED" - }, - "RecordState": "ARCHIVED" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-app/lambda-function-unused-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-app", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:05.837529+00:00", - "CreatedAt": "2020-06-15T20:24:05.837529+00:00", - "UpdatedAt": "2020-06-15T20:24:05.837529+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[Lambda.1] Lambda functions should be deleted after 30 days of no use", - "Description": "Lambda function serverless-flask-dev-app has not been used or updated in the last 30 days.", - "Remediation": { - "Recommendation": { - "Text": "For more information on best practices for lambda functions refer to the Best Practices for Working with AWS Lambda Functions section of the Amazon Lambda Developer Guide", - "Url": "https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-configuration" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsLambda", - "Id": "arn:aws:lambda:us-east-1:057637124865:function:serverless-flask-dev-app", - "Partition": "aws", - "Region": "us-east-1" - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.AM-2", - "NIST SP 800-53 CM-8", - "NIST SP 800-53 PM-5", - "AICPA TSC CC3.2", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.1.1", - "ISO 27001:2013 A.8.1.2", - "ISO 27001:2013 A.12.5.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev/apigateway-stage-metrics-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:09.274215+00:00", - "CreatedAt": "2020-06-15T20:24:09.274215+00:00", - "UpdatedAt": "2020-06-15T20:24:09.274215+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.1] API Gateway Rest API Stages should have CloudWatch Metrics enabled", - "Description": "API Gateway stage dev for Rest API dev-serverless-flask does not have CloudWatch metrics enabled. You can monitor API execution by using CloudWatch, which collects and processes raw data from API Gateway into readable, near-real-time metrics. These statistics are recorded for a period of 15 months so you can access historical information and gain a better perspective on how your web application or service is performing. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have CloudWatch Metrics enabled refer to the Monitor API Execution with Amazon CloudWatch section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/monitoring-cloudwatch.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "l6m7kr", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default/apigateway-stage-metrics-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:09.274215+00:00", - "CreatedAt": "2020-06-15T20:24:09.274215+00:00", - "UpdatedAt": "2020-06-15T20:24:09.274215+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.1] API Gateway Rest API Stages should have CloudWatch Metrics enabled", - "Description": "API Gateway stage default for Rest API workflow-callback-API does not have CloudWatch metrics enabled. You can monitor API execution by using CloudWatch, which collects and processes raw data from API Gateway into readable, near-real-time metrics. These statistics are recorded for a period of 15 months so you can access historical information and gain a better perspective on how your web application or service is performing. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have CloudWatch Metrics enabled refer to the Monitor API Execution with Amazon CloudWatch section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/monitoring-cloudwatch.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "bv4iij", - "stageName": "default" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev/apigateway-stage-metrics-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:09.274215+00:00", - "CreatedAt": "2020-06-15T20:24:09.274215+00:00", - "UpdatedAt": "2020-06-15T20:24:09.274215+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.1] API Gateway Rest API Stages should have CloudWatch Metrics enabled", - "Description": "API Gateway stage dev for Rest API dev-workflow does not have CloudWatch metrics enabled. You can monitor API execution by using CloudWatch, which collects and processes raw data from API Gateway into readable, near-real-time metrics. These statistics are recorded for a period of 15 months so you can access historical information and gain a better perspective on how your web application or service is performing. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have CloudWatch Metrics enabled refer to the Monitor API Execution with Amazon CloudWatch section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/monitoring-cloudwatch.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "k8x827", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev/apigateway-stage-api-logging-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:09.758802+00:00", - "CreatedAt": "2020-06-15T20:24:09.758802+00:00", - "UpdatedAt": "2020-06-15T20:24:09.758802+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.2] API Gateway Rest API Stages should have CloudWatch API Logging enabled", - "Description": "API Gateway stage dev for Rest API dev-serverless-flask does not have CloudWatch API Logging enabled. To help debug issues related to request execution or client access to your API, you can enable Amazon CloudWatch Logs to log API calls. The logged data includes errors or execution traces (such as request or response parameter values or payloads), data used by Lambda authorizers (formerly known as custom authorizers), whether API keys are required, whether usage plans are enabled, and so on. Refer to the remediation instructions if this configuration is not intended.", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have CloudWatch API Logging enabled refer to the Set Up CloudWatch API Logging in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "l6m7kr", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default/apigateway-stage-api-logging-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:09.758802+00:00", - "CreatedAt": "2020-06-15T20:24:09.758802+00:00", - "UpdatedAt": "2020-06-15T20:24:09.758802+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.2] API Gateway Rest API Stages should have CloudWatch API Logging enabled", - "Description": "API Gateway stage default for Rest API workflow-callback-API does not have CloudWatch API Logging enabled. To help debug issues related to request execution or client access to your API, you can enable Amazon CloudWatch Logs to log API calls. The logged data includes errors or execution traces (such as request or response parameter values or payloads), data used by Lambda authorizers (formerly known as custom authorizers), whether API keys are required, whether usage plans are enabled, and so on. Refer to the remediation instructions if this configuration is not intended.", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have CloudWatch API Logging enabled refer to the Set Up CloudWatch API Logging in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "bv4iij", - "stageName": "default" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev/apigateway-stage-api-logging-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:09.758802+00:00", - "CreatedAt": "2020-06-15T20:24:09.758802+00:00", - "UpdatedAt": "2020-06-15T20:24:09.758802+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.2] API Gateway Rest API Stages should have CloudWatch API Logging enabled", - "Description": "API Gateway stage dev for Rest API dev-workflow does not have CloudWatch API Logging enabled. To help debug issues related to request execution or client access to your API, you can enable Amazon CloudWatch Logs to log API calls. The logged data includes errors or execution traces (such as request or response parameter values or payloads), data used by Lambda authorizers (formerly known as custom authorizers), whether API keys are required, whether usage plans are enabled, and so on. Refer to the remediation instructions if this configuration is not intended.", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have CloudWatch API Logging enabled refer to the Set Up CloudWatch API Logging in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "k8x827", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev/apigateway-stage-caching-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:10.025742+00:00", - "CreatedAt": "2020-06-15T20:24:10.025742+00:00", - "UpdatedAt": "2020-06-15T20:24:10.025742+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.3] API Gateway Rest API Stages should have Caching enabled", - "Description": "API Gateway stage dev for Rest API dev-serverless-flask does not have Caching enabled. You can enable API caching in Amazon API Gateway to cache your endpoints responses. With caching, you can reduce the number of calls made to your endpoint and also improve the latency of requests to your API. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have caching enabled refer to the Enable API Caching to Enhance Responsiveness section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "l6m7kr", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.BE-5", - "NIST CSF PR.PT-5", - "NIST SP 800-53 CP-2", - "NIST SP 800-53 CP-11", - "NIST SP 800-53 SA-13", - "NIST SP 800-53 SA14", - "AICPA TSC CC3.1", - "AICPA TSC A1.2", - "ISO 27001:2013 A.11.1.4", - "ISO 27001:2013 A.17.1.1", - "ISO 27001:2013 A.17.1.2", - "ISO 27001:2013 A.17.2.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default/apigateway-stage-caching-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:10.025742+00:00", - "CreatedAt": "2020-06-15T20:24:10.025742+00:00", - "UpdatedAt": "2020-06-15T20:24:10.025742+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.3] API Gateway Rest API Stages should have Caching enabled", - "Description": "API Gateway stage default for Rest API workflow-callback-API does not have Caching enabled. You can enable API caching in Amazon API Gateway to cache your endpoints responses. With caching, you can reduce the number of calls made to your endpoint and also improve the latency of requests to your API. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have caching enabled refer to the Enable API Caching to Enhance Responsiveness section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "bv4iij", - "stageName": "default" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.BE-5", - "NIST CSF PR.PT-5", - "NIST SP 800-53 CP-2", - "NIST SP 800-53 CP-11", - "NIST SP 800-53 SA-13", - "NIST SP 800-53 SA14", - "AICPA TSC CC3.1", - "AICPA TSC A1.2", - "ISO 27001:2013 A.11.1.4", - "ISO 27001:2013 A.17.1.1", - "ISO 27001:2013 A.17.1.2", - "ISO 27001:2013 A.17.2.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev/apigateway-stage-caching-enabled-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:10.025742+00:00", - "CreatedAt": "2020-06-15T20:24:10.025742+00:00", - "UpdatedAt": "2020-06-15T20:24:10.025742+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.3] API Gateway Rest API Stages should have Caching enabled", - "Description": "API Gateway stage dev for Rest API dev-workflow does not have Caching enabled. You can enable API caching in Amazon API Gateway to cache your endpoints responses. With caching, you can reduce the number of calls made to your endpoint and also improve the latency of requests to your API. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have caching enabled refer to the Enable API Caching to Enhance Responsiveness section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "k8x827", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF ID.BE-5", - "NIST CSF PR.PT-5", - "NIST SP 800-53 CP-2", - "NIST SP 800-53 CP-11", - "NIST SP 800-53 SA-13", - "NIST SP 800-53 SA14", - "AICPA TSC CC3.1", - "AICPA TSC A1.2", - "ISO 27001:2013 A.11.1.4", - "ISO 27001:2013 A.17.1.1", - "ISO 27001:2013 A.17.1.2", - "ISO 27001:2013 A.17.2.1" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev/apigateway-stage-cache-encryption-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure" - ], - "FirstObservedAt": "2020-06-15T20:24:10.287523+00:00", - "CreatedAt": "2020-06-15T20:24:10.287523+00:00", - "UpdatedAt": "2020-06-15T20:24:10.287523+00:00", - "Severity": { - "Label": "HIGH" - }, - "Confidence": 99, - "Title": "[APIGateway.4] API Gateway Rest API Stages should have cache encryption enabled", - "Description": "API Gateway stage dev for Rest API dev-serverless-flask does not have cache encryption enabled. If you choose to enable caching for a REST API, you can enable cache encryption. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have caching encryption enabled refer to the Override API Gateway Stage-Level Caching for Method Caching section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html#override-api-gateway-stage-cache-for-method-cache" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "l6m7kr", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF PR.DS-1", - "NIST SP 800-53 MP-8", - "NIST SP 800-53 SC-12", - "NIST SP 800-53 SC-28", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.2.3" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default/apigateway-stage-cache-encryption-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure" - ], - "FirstObservedAt": "2020-06-15T20:24:10.287523+00:00", - "CreatedAt": "2020-06-15T20:24:10.287523+00:00", - "UpdatedAt": "2020-06-15T20:24:10.287523+00:00", - "Severity": { - "Label": "HIGH" - }, - "Confidence": 99, - "Title": "[APIGateway.4] API Gateway Rest API Stages should have cache encryption enabled", - "Description": "API Gateway stage default for Rest API workflow-callback-API does not have cache encryption enabled. If you choose to enable caching for a REST API, you can enable cache encryption. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have caching encryption enabled refer to the Override API Gateway Stage-Level Caching for Method Caching section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html#override-api-gateway-stage-cache-for-method-cache" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "bv4iij", - "stageName": "default" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF PR.DS-1", - "NIST SP 800-53 MP-8", - "NIST SP 800-53 SC-12", - "NIST SP 800-53 SC-28", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.2.3" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev/apigateway-stage-cache-encryption-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure" - ], - "FirstObservedAt": "2020-06-15T20:24:10.287523+00:00", - "CreatedAt": "2020-06-15T20:24:10.287523+00:00", - "UpdatedAt": "2020-06-15T20:24:10.287523+00:00", - "Severity": { - "Label": "HIGH" - }, - "Confidence": 99, - "Title": "[APIGateway.4] API Gateway Rest API Stages should have cache encryption enabled", - "Description": "API Gateway stage dev for Rest API dev-workflow does not have cache encryption enabled. If you choose to enable caching for a REST API, you can enable cache encryption. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have caching encryption enabled refer to the Override API Gateway Stage-Level Caching for Method Caching section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html#override-api-gateway-stage-cache-for-method-cache" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "k8x827", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF PR.DS-1", - "NIST SP 800-53 MP-8", - "NIST SP 800-53 SC-12", - "NIST SP 800-53 SC-28", - "AICPA TSC CC6.1", - "ISO 27001:2013 A.8.2.3" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev/apigateway-stage-xray-tracing-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:10.557861+00:00", - "CreatedAt": "2020-06-15T20:24:10.557861+00:00", - "UpdatedAt": "2020-06-15T20:24:10.557861+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.5] API Gateway Rest API Stages should have tracing enabled", - "Description": "API Gateway stage dev for Rest API dev-serverless-flask does not have tracing enabled. Because X-Ray gives you an end-to-end view of an entire request, you can analyze latencies in your APIs and their backend services. You can use an X-Ray service map to view the latency of an entire request and that of the downstream services that are integrated with X-Ray. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have tracing enabled refer to the Set Up X-Ray Tracing in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-set-up-tracing.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "l6m7kr", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default/apigateway-stage-xray-tracing-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:10.557861+00:00", - "CreatedAt": "2020-06-15T20:24:10.557861+00:00", - "UpdatedAt": "2020-06-15T20:24:10.557861+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.5] API Gateway Rest API Stages should have tracing enabled", - "Description": "API Gateway stage default for Rest API workflow-callback-API does not have tracing enabled. Because X-Ray gives you an end-to-end view of an entire request, you can analyze latencies in your APIs and their backend services. You can use an X-Ray service map to view the latency of an entire request and that of the downstream services that are integrated with X-Ray. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have tracing enabled refer to the Set Up X-Ray Tracing in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-set-up-tracing.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "bv4iij", - "stageName": "default" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev/apigateway-stage-xray-tracing-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices" - ], - "FirstObservedAt": "2020-06-15T20:24:10.557861+00:00", - "CreatedAt": "2020-06-15T20:24:10.557861+00:00", - "UpdatedAt": "2020-06-15T20:24:10.557861+00:00", - "Severity": { - "Label": "LOW" - }, - "Confidence": 99, - "Title": "[APIGateway.5] API Gateway Rest API Stages should have tracing enabled", - "Description": "API Gateway stage dev for Rest API dev-workflow does not have tracing enabled. Because X-Ray gives you an end-to-end view of an entire request, you can analyze latencies in your APIs and their backend services. You can use an X-Ray service map to view the latency of an entire request and that of the downstream services that are integrated with X-Ray. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should have tracing enabled refer to the Set Up X-Ray Tracing in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-set-up-tracing.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "k8x827", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-3", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 IR-5", - "NIST SP 800-53 IR-8", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.7" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev/apigateway-stage-waf-protection-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure" - ], - "FirstObservedAt": "2020-06-15T20:24:10.803572+00:00", - "CreatedAt": "2020-06-15T20:24:10.803572+00:00", - "UpdatedAt": "2020-06-15T20:24:10.803572+00:00", - "Severity": { - "Label": "HIGH" - }, - "Confidence": 99, - "Title": "[APIGateway.6] API Gateway Rest API Stages should be protected by an AWS WAF Web ACL", - "Description": "API Gateway stage dev for Rest API dev-serverless-flask is not protected by an AWS WAF Web ACL. You can use AWS WAF to protect your API Gateway API from common web exploits, such as SQL injection and cross-site scripting (XSS) attacks. These could affect API availability and performance, compromise security, or consume excessive resources. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should be protected by WAF refer to the Set Up AWS WAF in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-setup-waf.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/5dq0gatjul/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "l6m7kr", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-2", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.1", - "ISO 27001:2013 A.16.1.4" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default/apigateway-stage-waf-protection-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure" - ], - "FirstObservedAt": "2020-06-15T20:24:10.803572+00:00", - "CreatedAt": "2020-06-15T20:24:10.803572+00:00", - "UpdatedAt": "2020-06-15T20:24:10.803572+00:00", - "Severity": { - "Label": "HIGH" - }, - "Confidence": 99, - "Title": "[APIGateway.6] API Gateway Rest API Stages should be protected by an AWS WAF Web ACL", - "Description": "API Gateway stage default for Rest API workflow-callback-API is not protected by an AWS WAF Web ACL. You can use AWS WAF to protect your API Gateway API from common web exploits, such as SQL injection and cross-site scripting (XSS) attacks. These could affect API availability and performance, compromise security, or consume excessive resources. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should be protected by WAF refer to the Set Up AWS WAF in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-setup-waf.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9kb0qea893/stages/default", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "bv4iij", - "stageName": "default" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-2", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.1", - "ISO 27001:2013 A.16.1.4" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}, -{ - "SchemaVersion": "2018-10-08", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev/apigateway-stage-waf-protection-check", - "ProductArn": "arn:aws:securityhub:us-east-1:057637124865:product/057637124865/default", - "GeneratorId": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "AwsAccountId": "057637124865", - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure" - ], - "FirstObservedAt": "2020-06-15T20:24:10.803572+00:00", - "CreatedAt": "2020-06-15T20:24:10.803572+00:00", - "UpdatedAt": "2020-06-15T20:24:10.803572+00:00", - "Severity": { - "Label": "HIGH" - }, - "Confidence": 99, - "Title": "[APIGateway.6] API Gateway Rest API Stages should be protected by an AWS WAF Web ACL", - "Description": "API Gateway stage dev for Rest API dev-workflow is not protected by an AWS WAF Web ACL. You can use AWS WAF to protect your API Gateway API from common web exploits, such as SQL injection and cross-site scripting (XSS) attacks. These could affect API availability and performance, compromise security, or consume excessive resources. Refer to the remediation instructions if this configuration is not intended", - "Remediation": { - "Recommendation": { - "Text": "If your API Gateway stage should be protected by WAF refer to the Set Up AWS WAF in API Gateway section of the Amazon API Gateway Developer Guide", - "Url": "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-setup-waf.html" - } - }, - "ProductFields": { - "Product Name": "ElectricEye" - }, - "Resources": [ - { - "Type": "AwsApiGatewayRestApi", - "Id": "arn:aws:apigateway:us-east-1::/restapis/9zcwbrpvza/stages/dev", - "Partition": "aws", - "Region": "us-east-1", - "Details": { - "Other": { - "deploymentId": "k8x827", - "stageName": "dev" - } - } - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF DE.AE-2", - "NIST SP 800-53 AU-6", - "NIST SP 800-53 CA-7", - "NIST SP 800-53 IR-4", - "NIST SP 800-53 SI-4", - "AICPA TSC CC7.2", - "ISO 27001:2013 A.12.4.1", - "ISO 27001:2013 A.16.1.1", - "ISO 27001:2013 A.16.1.4" - ] - }, - "Workflow": { - "Status": "NEW" - }, - "RecordState": "ACTIVE" -}]} diff --git a/govcloud-auditors/AWS_KMS_Auditor.py b/govcloud-auditors/AWS_KMS_Auditor.py new file mode 100644 index 00000000..4c3ef4da --- /dev/null +++ b/govcloud-auditors/AWS_KMS_Auditor.py @@ -0,0 +1,247 @@ +# This file is part of ElectricEye. + +# ElectricEye is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# ElectricEye is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License along with ElectricEye. +# If not, see https://github.com/jonrau1/ElectricEye/blob/master/LICENSE. + +import boto3 +import datetime +import json +import os +from auditors.Auditor import Auditor + +# import boto3 clients +sts = boto3.client("sts") +kms = boto3.client("kms") + +class KMSKeyRotationCheck(Auditor): + def execute(self): + awsAccountId = sts.get_caller_identity()["Account"] + awsRegion = os.environ["AWS_REGION"] + keys = kms.list_keys() + my_keys = keys["Keys"] + for key in my_keys: + keyid = key["KeyId"] + keyarn = key["KeyArn"] + key_rotation = kms.get_key_rotation_status(KeyId=keyid) + iso8601Time = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat() + if key_rotation["KeyRotationEnabled"] == True: + finding = { + "SchemaVersion": "2018-10-08", + "Id": keyarn + "/kms-key-rotation-check", + "ProductArn": "arn:aws-us-gov:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": keyarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "INFORMATIONAL"}, + "Confidence": 99, + "Title": "[KMS.1] KMS keys should have key rotation enabled", + "Description": "KMS Key " + + keyid + + " does have key rotation enabled.", + "Remediation": { + "Recommendation": { + "Text": "For more information on KMS key rotation refer to the AWS KMS Developer Guide on Rotating Keys", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsKey", + "Id": keyarn, + "Partition": "aws-us-gov", + "Region": awsRegion, + "Details": {"AwsKmsKey": {"KeyId": keyid}}, + } + ], + "Compliance": { + "Status": "PASSED" + }, + "Workflow": {"Status": "RESOLVED"}, + "RecordState": "ARCHIVED", + } + yield finding + else: + finding = { + 'SchemaVersion': '2018-10-08', + 'Id': keyarn + '/kms-key-rotation-check', + 'ProductArn': 'arn:aws-us-gov:securityhub:' + awsRegion + ':' + awsAccountId + ':product/' + awsAccountId + '/default', + 'GeneratorId': keyarn, + 'AwsAccountId': awsAccountId, + 'Types': [ 'Software and Configuration Checks/AWS Security Best Practices' ], + 'FirstObservedAt': iso8601Time, + 'CreatedAt': iso8601Time, + 'UpdatedAt': iso8601Time, + 'Severity': { 'Label': 'MEDIUM' }, + 'Confidence': 99, + 'Title': '[KMS.1] KMS keys should have key rotation enabled', + 'Description': 'KMS key ' + keyid + ' does not have key rotation enabled.', + 'Remediation': { + 'Recommendation': { + 'Text': 'For more information on KMS key rotation refer to the AWS KMS Developer Guide on Rotating Keys', + 'Url': 'https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html' + } + }, + 'ProductFields': { + 'Product Name': 'ElectricEye' + }, + 'Resources': [ + { + 'Type': 'AwsKmsKey', + 'Id': keyarn, + 'Partition': 'aws-us-gov', + 'Region': awsRegion, + 'Details': { + 'AwsKmsKey': { 'KeyId': keyid } + } + } + ], + 'Compliance': { + 'Status': 'FAILED' + }, + 'Workflow': { + 'Status': 'NEW' + }, + 'RecordState': 'ACTIVE' + } + yield finding + +class KMSKeyExposedCheck(Auditor): + def execute(self): + awsAccountId = sts.get_caller_identity()["Account"] + awsRegion = os.environ["AWS_REGION"] + response = kms.list_aliases() + aliasList = response["Aliases"] + for alias in aliasList: + if "TargetKeyId" in alias: + aliasArn = alias["AliasArn"] + keyid = alias["TargetKeyId"] + policyString = kms.get_key_policy(KeyId=keyid, PolicyName="default") + fail = False + policy_json = policyString["Policy"] + policy = json.loads(policy_json) + iso8601Time = ( + datetime.datetime.utcnow() + .replace(tzinfo=datetime.timezone.utc) + .isoformat() + ) + for sid in policy["Statement"]: + access = sid["Principal"].get("AWS", None) + if access != "*" or (access == "*" and "Condition" in sid): + continue + else: + fail = True + break + if not fail: + finding = { + "SchemaVersion": "2018-10-08", + "Id": aliasArn + "/kms-key-exposed-check", + "ProductArn": "arn:aws-us-gov:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": aliasArn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "INFORMATIONAL"}, + "Confidence": 75, # The Condition may not effectively limit access + "Title": "[KMS.2] KMS keys should not have public access", + "Description": "KMS key " + + keyid + + " does not have public access or limited by a Condition. Refer to the remediation instructions to review kms access policy", + "Remediation": { + "Recommendation": { + "Text": "For more information on AWS KMS key policies refer to Using key policies in AWS KMS section of the AWS KMS Developer Guide.", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsAlias", + "Id": aliasArn, + "Partition": "aws-us-gov", + "Region": awsRegion, + } + ], + "Compliance": {"Status": "PASSED"}, + "Workflow": {"Status": "RESOLVED"}, + "RecordState": "ARCHIVED", + } + yield finding + else: + finding = { + "SchemaVersion": "2018-10-08", + "Id": aliasArn + "/kms-key-exposed-check", + "ProductArn": "arn:aws-us-gov:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": aliasArn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "HIGH"}, + "Confidence": 99, + "Title": "[KMS.2] KMS keys should not have public access", + "Description": "KMS key " + + keyid + + " has public access. Refer to the remediation instructions to review kms access policy", + "Remediation": { + "Recommendation": { + "Text": "For more information on AWS KMS key policies refer to Using key policies in AWS KMS section of the AWS KMS Developer Guide.", + "Url": "https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsKmsAlias", + "Id": aliasArn, + "Partition": "aws-us-gov", + "Region": awsRegion, + } + ], + "Compliance": {"Status": "FAILED"}, + "Workflow": {"Status": "NEW"}, + "RecordState": "ACTIVE", + } + yield finding diff --git a/govcloud-auditors/Amazon_SNS_Auditor.py b/govcloud-auditors/Amazon_SNS_Auditor.py index e9d07a5a..e6bf6dee 100644 --- a/govcloud-auditors/Amazon_SNS_Auditor.py +++ b/govcloud-auditors/Amazon_SNS_Auditor.py @@ -316,7 +316,7 @@ def execute(self): fail = False # this results in one finding per topic instead of one finding per statement for sid in statement["Statement"]: - access = sid["Principal"]["aws-us-gov"] + access = sid["Principal"].get("aws-us-gov", None) iso8601Time = ( datetime.datetime.utcnow() .replace(tzinfo=datetime.timezone.utc) @@ -469,143 +469,151 @@ def execute(self): response = sns.get_topic_attributes(TopicArn=topicarn) myPolicy_json = str(response["Attributes"]["Policy"]) myPolicy = json.loads(myPolicy_json) + fail = False for statement in myPolicy["Statement"]: - principal = statement["Principal"]["aws-us-gov"] + principal = statement["Principal"].get("aws-us-gov", None) iso8601Time = ( datetime.datetime.utcnow() .replace(tzinfo=datetime.timezone.utc) .isoformat() ) - if principal[0] != "*": - if not principal[0].isdigit(): + if principal and principal != "*": + if not principal.isdigit(): + # This assumes if it is not a digit that it must be an arn. + # not sure if this is a safe assumption. principal = principal.split(":")[4] if principal == awsAccountId: - finding = { - "SchemaVersion": "2018-10-08", - "Id": topicarn + "/sns-cross-account-check", - "ProductArn": "arn:aws-us-gov:securityhub:" - + awsRegion - + ":" - + awsAccountId - + ":product/" - + awsAccountId - + "/default", - "GeneratorId": topicarn, - "AwsAccountId": awsAccountId, - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure", - ], - "FirstObservedAt": iso8601Time, - "CreatedAt": iso8601Time, - "UpdatedAt": iso8601Time, - "Severity": {"Label": "INFORMATIONAL"}, - "Confidence": 99, - "Title": "[SNS.4] SNS topics should not allow cross-account access", - "Description": "SNS topic " - + topicName - + " does not have cross-account access.", - "Remediation": { - "Recommendation": { - "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", - "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", - } - }, - "ProductFields": {"Product Name": "ElectricEye"}, - "Resources": [ - { - "Type": "AwsSnsTopic", - "Id": topicarn, - "Partition": "aws-us-gov", - "Region": awsRegion, - "Details": { - "AwsSnsTopic": {"TopicName": topicName} - }, - } - ], - "Compliance": { - "Status": "PASSED", - "RelatedRequirements": [ - "NIST CSF PR.AC-3", - "NIST SP 800-53 AC-1", - "NIST SP 800-53 AC-17", - "NIST SP 800-53 AC-19", - "NIST SP 800-53 AC-20", - "NIST SP 800-53 SC-15", - "AICPA TSC CC6.6", - "ISO 27001:2013 A.6.2.1", - "ISO 27001:2013 A.6.2.2", - "ISO 27001:2013 A.11.2.6", - "ISO 27001:2013 A.13.1.1", - "ISO 27001:2013 A.13.2.1", - ], - }, - "Workflow": {"Status": "RESOLVED"}, - "RecordState": "ARCHIVED", - } - yield finding + continue else: - finding = { - "SchemaVersion": "2018-10-08", - "Id": topicarn + "/sns-cross-account-check", - "ProductArn": "arn:aws-us-gov:securityhub:" - + awsRegion - + ":" - + awsAccountId - + ":product/" - + awsAccountId - + "/default", - "GeneratorId": topicarn, - "AwsAccountId": awsAccountId, - "Types": [ - "Software and Configuration Checks/AWS Security Best Practices", - "Effects/Data Exposure", - ], - "FirstObservedAt": iso8601Time, - "CreatedAt": iso8601Time, - "UpdatedAt": iso8601Time, - "Severity": {"Label": "Low"}, - "Confidence": 99, - "Title": "[SNS.4] SNS topics should not allow cross-account access", - "Description": "SNS topic " - + topicName - + " has cross-account access.", - "Remediation": { - "Recommendation": { - "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", - "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", - } + fail = True + break + if not fail: + finding = { + "SchemaVersion": "2018-10-08", + "Id": topicarn + "/sns-cross-account-check", + "ProductArn": "arn:aws-us-gov:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": topicarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "INFORMATIONAL"}, + "Confidence": 99, + "Title": "[SNS.4] SNS topics should not allow cross-account access", + "Description": "SNS topic " + + topicName + + " does not have cross-account access.", + "Remediation": { + "Recommendation": { + "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", + "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsSnsTopic", + "Id": topicarn, + "Partition": "aws-us-gov", + "Region": awsRegion, + "Details": { + "AwsSnsTopic": {"TopicName": topicName} }, - "ProductFields": {"Product Name": "ElectricEye"}, - "Resources": [ - { - "Type": "AwsSnsTopic", - "Id": topicarn, - "Partition": "aws-us-gov", - "Region": awsRegion, - "Details": { - "AwsSnsTopic": {"TopicName": topicName} - }, - } - ], - "Compliance": { - "Status": "FAILED", - "RelatedRequirements": [ - "NIST CSF PR.AC-3", - "NIST SP 800-53 AC-1", - "NIST SP 800-53 AC-17", - "NIST SP 800-53 AC-19", - "NIST SP 800-53 AC-20", - "NIST SP 800-53 SC-15", - "AICPA TSC CC6.6", - "ISO 27001:2013 A.6.2.1", - "ISO 27001:2013 A.6.2.2", - "ISO 27001:2013 A.11.2.6", - "ISO 27001:2013 A.13.1.1", - "ISO 27001:2013 A.13.2.1", - ], + } + ], + "Compliance": { + "Status": "PASSED", + "RelatedRequirements": [ + "NIST CSF PR.AC-3", + "NIST SP 800-53 AC-1", + "NIST SP 800-53 AC-17", + "NIST SP 800-53 AC-19", + "NIST SP 800-53 AC-20", + "NIST SP 800-53 SC-15", + "AICPA TSC CC6.6", + "ISO 27001:2013 A.6.2.1", + "ISO 27001:2013 A.6.2.2", + "ISO 27001:2013 A.11.2.6", + "ISO 27001:2013 A.13.1.1", + "ISO 27001:2013 A.13.2.1", + ], + }, + "Workflow": {"Status": "RESOLVED"}, + "RecordState": "ARCHIVED", + } + yield finding + else: + finding = { + "SchemaVersion": "2018-10-08", + "Id": topicarn + "/sns-cross-account-check", + "ProductArn": "arn:aws-us-gov:securityhub:" + + awsRegion + + ":" + + awsAccountId + + ":product/" + + awsAccountId + + "/default", + "GeneratorId": topicarn, + "AwsAccountId": awsAccountId, + "Types": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure", + ], + "FirstObservedAt": iso8601Time, + "CreatedAt": iso8601Time, + "UpdatedAt": iso8601Time, + "Severity": {"Label": "Low"}, + "Confidence": 99, + "Title": "[SNS.4] SNS topics should not allow cross-account access", + "Description": "SNS topic " + + topicName + + " has cross-account access.", + "Remediation": { + "Recommendation": { + "Text": "For more information on SNS best practices refer to the Amazon SNS security best practices section of the Amazon Simple Notification Service Developer Guide.", + "Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit", + } + }, + "ProductFields": {"Product Name": "ElectricEye"}, + "Resources": [ + { + "Type": "AwsSnsTopic", + "Id": topicarn, + "Partition": "aws-us-gov", + "Region": awsRegion, + "Details": { + "AwsSnsTopic": {"TopicName": topicName} }, - "Workflow": {"Status": "NEW"}, - "RecordState": "ACTIVE", } - yield finding + ], + "Compliance": { + "Status": "FAILED", + "RelatedRequirements": [ + "NIST CSF PR.AC-3", + "NIST SP 800-53 AC-1", + "NIST SP 800-53 AC-17", + "NIST SP 800-53 AC-19", + "NIST SP 800-53 AC-20", + "NIST SP 800-53 SC-15", + "AICPA TSC CC6.6", + "ISO 27001:2013 A.6.2.1", + "ISO 27001:2013 A.6.2.2", + "ISO 27001:2013 A.11.2.6", + "ISO 27001:2013 A.13.1.1", + "ISO 27001:2013 A.13.2.1", + ], + }, + "Workflow": {"Status": "NEW"}, + "RecordState": "ACTIVE", + } + yield finding diff --git a/govcloud-auditors/tests/test_AWS_KMS_Auditor.py b/govcloud-auditors/tests/test_AWS_KMS_Auditor.py new file mode 100644 index 00000000..219080b3 --- /dev/null +++ b/govcloud-auditors/tests/test_AWS_KMS_Auditor.py @@ -0,0 +1,159 @@ +import datetime +import json +import os +import pytest +from botocore.stub import Stubber, ANY +from auditors.AWS_KMS_Auditor import ( + KMSKeyRotationCheck, + KMSKeyExposedCheck, + sts, + kms, +) + +# not available in local testing without ECS +os.environ["AWS_REGION"] = "us-east-1" +# for local testing, don't assume default profile exists +os.environ["AWS_DEFAULT_REGION"] = "us-east-1" + +sts_response = { + "Account": "012345678901", + "Arn": "arn:aws:iam::012345678901:user/user", +} + +list_aliases_response = { + "Aliases": [ + { + "AliasArn": "arn:aws:kms:us-east-1:012345678901:alias/aws/s3", + "TargetKeyId": "c84a8fab-6c42-4b33-ad64-a8e0b0ec0a15", + }, + ], +} + +get_key_policy_public_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"AWS": "*"},"Action": "kms:*","Resource": "*"}]}' +} + +get_key_policy_not_public_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"AWS": "012345678901"},"Action": "kms:*","Resource": "*"}]}' +} + +get_key_policy_has_condition_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"AWS": "*"},"Action": "kms:*","Resource": "*","Condition": {"StringEquals": {"kms:CallerAccount": "012345678901","kms:ViaService": "sns.us-east-1.amazonaws.com"}}}]}' +} + +get_key_policy_no_AWS_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"Service": "cloudtrail.amazonaws.com"},"Action": "kms:*","Resource": "*","Condition": {"StringEquals": {"kms:CallerAccount": "012345678901","kms:ViaService": "sns.us-east-1.amazonaws.com"}}}]}' +} + +list_keys_response = { + "Keys": [ + { + "KeyId": "273e5d8e-4746-4ba9-be3a-4dce36783814", + "KeyArn": "arn:aws:kms:us-east-1:012345678901:key/273e5d8e-4746-4ba9-be3a-4dce36783814" + } + ] +} + +get_key_rotation_status_response = { + "KeyRotationEnabled": True +} + +get_key_rotation_status_response1 = { + "KeyRotationEnabled": False +} + +@pytest.fixture(scope="function") +def sts_stubber(): + sts_stubber = Stubber(sts) + sts_stubber.activate() + yield sts_stubber + sts_stubber.deactivate() + + +@pytest.fixture(scope="function") +def kms_stubber(): + kms_stubber = Stubber(kms) + kms_stubber.activate() + yield kms_stubber + kms_stubber.deactivate() + +def test_key_rotation_enabled(sts_stubber, kms_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_keys", list_keys_response) + kms_stubber.add_response("get_key_rotation_status", get_key_rotation_status_response) + check = KMSKeyRotationCheck() + results = check.execute() + for result in results: + if "273e5d8e-4746-4ba9-be3a-4dce36783814" in result["Id"]: + print(result["Id"]) + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_key_rotation_not_enabled(sts_stubber, kms_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_keys", list_keys_response) + kms_stubber.add_response("get_key_rotation_status", get_key_rotation_status_response1) + check = KMSKeyRotationCheck() + results = check.execute() + for result in results: + if "273e5d8e-4746-4ba9-be3a-4dce36783814" in result["Id"]: + print(result["Id"]) + assert result["RecordState"] == "ACTIVE" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_has_public_key(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_public_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + assert result["RecordState"] == "ACTIVE" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_no_public_key(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_not_public_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + print(result["Id"]) + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_has_condition(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_has_condition_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_no_AWS(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_no_AWS_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() diff --git a/govcloud-auditors/tests/test_Amazon_SNS_Auditor.py b/govcloud-auditors/tests/test_Amazon_SNS_Auditor.py index d355b047..b8e0346c 100644 --- a/govcloud-auditors/tests/test_Amazon_SNS_Auditor.py +++ b/govcloud-auditors/tests/test_Amazon_SNS_Auditor.py @@ -26,6 +26,12 @@ "Topics": [{"TopicArn": "arn:aws-us-gov:sns:us-east-1:012345678901:MyTopic"},], } +get_topic_attributes_no_AWS = { + "Attributes": { + "Policy": '{"Version": "2008-10-17","Id": "__default_policy_ID","Statement": [{"Sid": "__default_statement_ID","Effect": "Allow","Principal": {"AWS": "*"},"Action": ["SNS:GetTopicAttributes","SNS:SetTopicAttributes","SNS:AddPermission","SNS:RemovePermission","SNS:DeleteTopic","SNS:Subscribe","SNS:ListSubscriptionsByTopic","SNS:Publish","SNS:Receive"],"Resource": "arn:aws:sns:us-east-1:012345678901:cloudtrail-sns","Condition": {"StringEquals": {"AWS:SourceOwner": "012345678901"}}},{"Sid": "AWSCloudTrailSNSPolicy20150319","Effect": "Allow","Principal": {"Service": "cloudtrail.amazonaws.com"},"Action": "SNS:Publish","Resource": "arn:aws:sns:us-east-1:012345678901:cloudtrail-sns"}]}' + } +} + get_topic_attributes_arn_response = { "Attributes": { "Policy": '{"Statement":[{"Principal":{"AWS":"arn:aws-us-gov:iam::012345678901:root"},"Condition":{"StringEquals":{"aws-us-gov:SourceOwner":"012345678901"}}}]}', @@ -45,19 +51,19 @@ get_topic_attributes_response1 = { "Attributes": { - "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"arn:aws-us-gov:iam::012345678901:root"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:Test"}]}' + "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"arn:aws-us-gov:iam::012345678901:root"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:MyTopic"}]}' } } get_topic_attributes_response2 = { "Attributes": { - "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:GetTopicAttributes","SNS:SetTopicAttributes","SNS:AddPermission","SNS:RemovePermission","SNS:DeleteTopic","SNS:Subscribe","SNS:ListSubscriptionsByTopic","SNS:Publish","SNS:Receive"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:Test","Condition":{"StringEquals":{"aws-us-gov:SourceOwner":"012345678901"}}}]}' + "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:GetTopicAttributes","SNS:SetTopicAttributes","SNS:AddPermission","SNS:RemovePermission","SNS:DeleteTopic","SNS:Subscribe","SNS:ListSubscriptionsByTopic","SNS:Publish","SNS:Receive"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:MyTopic","Condition":{"StringEquals":{"aws-us-gov:SourceOwner":"012345678901"}}}]}' } } get_topic_attributes_response3 = { "Attributes": { - "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:Test","Condition":{"StringEquals":{"aws-us-gov:SourceOwner":"012345678901"}}},{"Sid":"__console_pub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":"SNS:Publish","Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:Test"},{"Sid":"__console_sub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Subscribe","SNS:Receive"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:Test"}]}' + "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:MyTopic","Condition":{"StringEquals":{"aws-us-gov:SourceOwner":"012345678901"}}},{"Sid":"__console_pub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":"SNS:Publish","Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:MyTopic"},{"Sid":"__console_sub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Subscribe","SNS:Receive"],"Resource":"arn:aws-us-gov:sns:us-east-1:012345678901:MyTopic"}]}' } } @@ -124,6 +130,20 @@ def test_id_not_principal(sns_stubber, sts_stubber): assert result["RecordState"] == "ACTIVE" sns_stubber.assert_no_pending_responses() +def test_no_AWS(sns_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + sns_stubber.add_response("list_topics", list_topics_response) + sns_stubber.add_response( + "get_topic_attributes", get_topic_attributes_no_AWS + ) + check = SNSCrossAccountCheck() + results = check.execute() + for result in results: + if "MyTopic" in result["Id"]: + assert result["RecordState"] == "ARCHIVED" + else: + assert False + sns_stubber.assert_no_pending_responses() def test_no_access(sts_stubber, sns_stubber): sts_stubber.add_response("get_caller_identity", sts_response) @@ -132,7 +152,7 @@ def test_no_access(sts_stubber, sns_stubber): check = SNSPublicAccessCheck() results = check.execute() for result in results: - if "Test" in result["Id"]: + if "MyTopic" in result["Id"]: assert result["RecordState"] == "ARCHIVED" else: assert False @@ -146,7 +166,7 @@ def test_has_a_condition(sts_stubber, sns_stubber): check = SNSPublicAccessCheck() results = check.execute() for result in results: - if "Test" in result["Id"]: + if "MyTopic" in result["Id"]: assert result["RecordState"] == "ARCHIVED" else: assert False @@ -160,7 +180,22 @@ def test_has_public_access(sts_stubber, sns_stubber): check = SNSPublicAccessCheck() results = check.execute() for result in results: - if "Test" in result["Id"]: + if "MyTopic" in result["Id"]: + assert result["RecordState"] == "ACTIVE" + else: + assert False + sns_stubber.assert_no_pending_responses() + +def test_no_AWS_Public(sns_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + sns_stubber.add_response("list_topics", list_topics_response) + sns_stubber.add_response( + "get_topic_attributes", get_topic_attributes_no_AWS + ) + check = SNSPublicAccessCheck() + results = check.execute() + for result in results: + if "MyTopic" in result["Id"]: assert result["RecordState"] == "ARCHIVED" else: assert False diff --git a/policies/Instance_Profile_IAM_Policy.json b/policies/Instance_Profile_IAM_Policy.json index 83c41403..fd423f41 100644 --- a/policies/Instance_Profile_IAM_Policy.json +++ b/policies/Instance_Profile_IAM_Policy.json @@ -232,7 +232,11 @@ "ecr:GetRepositoryPolicy", "lambda:ListFunctions", "cloudwatch:GetMetricData", - "sns:GetTopicAttributes" + "sns:GetTopicAttributes", + "kms:ListAliases", + "kms:GetKeyPolicy", + "kms:ListKeys", + "kms:GetKeyRotationStatus" ], "Resource": "*" } diff --git a/terraform-config-files/electric_eye.tf b/terraform-config-files/electric_eye.tf index e7d6bcb6..b3ef73e9 100644 --- a/terraform-config-files/electric_eye.tf +++ b/terraform-config-files/electric_eye.tf @@ -338,7 +338,11 @@ resource "aws_iam_role_policy" "Electric_Eye_Task_Role_Policy" { "ecr:GetRepositoryPolicy", "rds:DescribeDBClusterParameterGroups", "lambda:ListFunctions", - "cloudwatch:GetMetricData" + "cloudwatch:GetMetricData", + "kms:ListAliases", + "kms:GetKeyPolicy", + "kms:ListKeys", + "kms:GetKeyRotationStatus" ], "Resource": "*" } diff --git a/tests/test_AWS_KMS_Auditor.py b/tests/test_AWS_KMS_Auditor.py new file mode 100644 index 00000000..8963519e --- /dev/null +++ b/tests/test_AWS_KMS_Auditor.py @@ -0,0 +1,158 @@ +import datetime +import json +import os +import pytest +from botocore.stub import Stubber, ANY +from auditors.AWS_KMS_Auditor import ( + KMSKeyRotationCheck, + KMSKeyExposedCheck, + sts, + kms, +) + +# not available in local testing without ECS +os.environ["AWS_REGION"] = "us-east-1" +# for local testing, don't assume default profile exists +os.environ["AWS_DEFAULT_REGION"] = "us-east-1" + +sts_response = { + "Account": "012345678901", + "Arn": "arn:aws:iam::012345678901:user/user", +} + +list_aliases_response = { + "Aliases": [ + { + "AliasArn": "arn:aws:kms:us-east-1:012345678901:alias/aws/s3", + "TargetKeyId": "c84a8fab-6c42-4b33-ad64-a8e0b0ec0a15", + }, + ], +} + +get_key_policy_public_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"AWS": "*"},"Action": "kms:*","Resource": "*"}]}' +} + +get_key_policy_not_public_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"AWS": "012345678901"},"Action": "kms:*","Resource": "*"}]}' +} + +get_key_policy_has_condition_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"AWS": "*"},"Action": "kms:*","Resource": "*","Condition": {"StringEquals": {"kms:CallerAccount": "012345678901","kms:ViaService": "sns.us-east-1.amazonaws.com"}}}]}' +} + +get_key_policy_no_AWS_response = { + "Policy": '{"Version": "2012-10-17","Id": "KeyPolicy1568312239560","Statement": [{"Sid": "StmtID1672312238115","Effect": "Allow","Principal": {"Service": "cloudtrail.amazonaws.com"},"Action": "kms:*","Resource": "*","Condition": {"StringEquals": {"kms:CallerAccount": "012345678901","kms:ViaService": "sns.us-east-1.amazonaws.com"}}}]}' +} + +list_keys_response = { + "Keys": [ + { + "KeyId": "273e5d8e-4746-4ba9-be3a-4dce36783814", + "KeyArn": "arn:aws:kms:us-east-1:012345678901:key/273e5d8e-4746-4ba9-be3a-4dce36783814" + } + ] +} + +get_key_rotation_status_response = { + "KeyRotationEnabled": True +} + +get_key_rotation_status_response1 = { + "KeyRotationEnabled": False +} + +@pytest.fixture(scope="function") +def sts_stubber(): + sts_stubber = Stubber(sts) + sts_stubber.activate() + yield sts_stubber + sts_stubber.deactivate() + +@pytest.fixture(scope="function") +def kms_stubber(): + kms_stubber = Stubber(kms) + kms_stubber.activate() + yield kms_stubber + kms_stubber.deactivate() + +def test_key_rotation_enabled(sts_stubber, kms_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_keys", list_keys_response) + kms_stubber.add_response("get_key_rotation_status", get_key_rotation_status_response) + check = KMSKeyRotationCheck() + results = check.execute() + for result in results: + if "273e5d8e-4746-4ba9-be3a-4dce36783814" in result["Id"]: + print(result["Id"]) + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_key_rotation_not_enabled(sts_stubber, kms_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_keys", list_keys_response) + kms_stubber.add_response("get_key_rotation_status", get_key_rotation_status_response1) + check = KMSKeyRotationCheck() + results = check.execute() + for result in results: + if "273e5d8e-4746-4ba9-be3a-4dce36783814" in result["Id"]: + print(result["Id"]) + assert result["RecordState"] == "ACTIVE" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_has_public_key(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_public_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + assert result["RecordState"] == "ACTIVE" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_no_public_key(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_not_public_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + print(result["Id"]) + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_has_condition(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_has_condition_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() + +def test_no_AWS(kms_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + kms_stubber.add_response("list_aliases", list_aliases_response) + kms_stubber.add_response("get_key_policy", get_key_policy_no_AWS_response) + check = KMSKeyExposedCheck() + results = check.execute() + for result in results: + if "s3" in result["Id"]: + assert result["RecordState"] == "ARCHIVED" + else: + assert False + kms_stubber.assert_no_pending_responses() diff --git a/tests/test_Amazon_SNS_Auditor.py b/tests/test_Amazon_SNS_Auditor.py index 430b3db5..a3afbf96 100644 --- a/tests/test_Amazon_SNS_Auditor.py +++ b/tests/test_Amazon_SNS_Auditor.py @@ -26,6 +26,12 @@ "Topics": [{"TopicArn": "arn:aws:sns:us-east-1:012345678901:MyTopic"},], } +get_topic_attributes_no_AWS = { + "Attributes": { + "Policy": '{"Version": "2008-10-17","Id": "__default_policy_ID","Statement": [{"Sid": "__default_statement_ID","Effect": "Allow","Principal": {"AWS": "*"},"Action": ["SNS:GetTopicAttributes","SNS:SetTopicAttributes","SNS:AddPermission","SNS:RemovePermission","SNS:DeleteTopic","SNS:Subscribe","SNS:ListSubscriptionsByTopic","SNS:Publish","SNS:Receive"],"Resource": "arn:aws:sns:us-east-1:012345678901:cloudtrail-sns","Condition": {"StringEquals": {"AWS:SourceOwner": "012345678901"}}},{"Sid": "AWSCloudTrailSNSPolicy20150319","Effect": "Allow","Principal": {"Service": "cloudtrail.amazonaws.com"},"Action": "SNS:Publish","Resource": "arn:aws:sns:us-east-1:012345678901:cloudtrail-sns"}]}' + } +} + get_topic_attributes_arn_response = { "Attributes": { "Policy": '{"Statement":[{"Principal":{"AWS":"arn:aws:iam::012345678901:root"},"Condition":{"StringEquals":{"AWS:SourceOwner":"012345678901"}}}]}', @@ -45,19 +51,19 @@ get_topic_attributes_response1 = { "Attributes": { - "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::012345678901:root"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws:sns:us-east-1:012345678901:Test"}]}' + "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::012345678901:root"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws:sns:us-east-1:012345678901:MyTopic"}]}' } } get_topic_attributes_response2 = { "Attributes": { - "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:GetTopicAttributes","SNS:SetTopicAttributes","SNS:AddPermission","SNS:RemovePermission","SNS:DeleteTopic","SNS:Subscribe","SNS:ListSubscriptionsByTopic","SNS:Publish","SNS:Receive"],"Resource":"arn:aws:sns:us-east-1:012345678901:Test","Condition":{"StringEquals":{"AWS:SourceOwner":"012345678901"}}}]}' + "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:GetTopicAttributes","SNS:SetTopicAttributes","SNS:AddPermission","SNS:RemovePermission","SNS:DeleteTopic","SNS:Subscribe","SNS:ListSubscriptionsByTopic","SNS:Publish","SNS:Receive"],"Resource":"arn:aws:sns:us-east-1:012345678901:MyTopic","Condition":{"StringEquals":{"AWS:SourceOwner":"012345678901"}}}]}' } } get_topic_attributes_response3 = { "Attributes": { - "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws:sns:us-east-1:012345678901:Test","Condition":{"StringEquals":{"AWS:SourceOwner":"012345678901"}}},{"Sid":"__console_pub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":"SNS:Publish","Resource":"arn:aws:sns:us-east-1:012345678901:Test"},{"Sid":"__console_sub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Subscribe","SNS:Receive"],"Resource":"arn:aws:sns:us-east-1:012345678901:Test"}]}' + "Policy": '{"Version":"2008-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"__default_statement_ID","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Publish","SNS:RemovePermission","SNS:SetTopicAttributes","SNS:DeleteTopic","SNS:ListSubscriptionsByTopic","SNS:GetTopicAttributes","SNS:Receive","SNS:AddPermission","SNS:Subscribe"],"Resource":"arn:aws:sns:us-east-1:012345678901:MyTopic","Condition":{"StringEquals":{"AWS:SourceOwner":"012345678901"}}},{"Sid":"__console_pub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":"SNS:Publish","Resource":"arn:aws:sns:us-east-1:012345678901:MyTopic"},{"Sid":"__console_sub_0","Effect":"Allow","Principal":{"AWS":"*"},"Action":["SNS:Subscribe","SNS:Receive"],"Resource":"arn:aws:sns:us-east-1:012345678901:MyTopic"}]}' } } @@ -124,6 +130,20 @@ def test_id_not_principal(sns_stubber, sts_stubber): assert result["RecordState"] == "ACTIVE" sns_stubber.assert_no_pending_responses() +def test_no_AWS(sns_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + sns_stubber.add_response("list_topics", list_topics_response) + sns_stubber.add_response( + "get_topic_attributes", get_topic_attributes_no_AWS + ) + check = SNSCrossAccountCheck() + results = check.execute() + for result in results: + if "MyTopic" in result["Id"]: + assert result["RecordState"] == "ARCHIVED" + else: + assert False + sns_stubber.assert_no_pending_responses() def test_no_access(sts_stubber, sns_stubber): sts_stubber.add_response("get_caller_identity", sts_response) @@ -132,7 +152,7 @@ def test_no_access(sts_stubber, sns_stubber): check = SNSPublicAccessCheck() results = check.execute() for result in results: - if "Test" in result["Id"]: + if "MyTopic" in result["Id"]: assert result["RecordState"] == "ARCHIVED" else: assert False @@ -146,7 +166,7 @@ def test_has_a_condition(sts_stubber, sns_stubber): check = SNSPublicAccessCheck() results = check.execute() for result in results: - if "Test" in result["Id"]: + if "MyTopic" in result["Id"]: assert result["RecordState"] == "ARCHIVED" else: assert False @@ -160,7 +180,22 @@ def test_has_public_access(sts_stubber, sns_stubber): check = SNSPublicAccessCheck() results = check.execute() for result in results: - if "Test" in result["Id"]: + if "MyTopic" in result["Id"]: + assert result["RecordState"] == "ACTIVE" + else: + assert False + sns_stubber.assert_no_pending_responses() + +def test_no_AWS_Public(sns_stubber, sts_stubber): + sts_stubber.add_response("get_caller_identity", sts_response) + sns_stubber.add_response("list_topics", list_topics_response) + sns_stubber.add_response( + "get_topic_attributes", get_topic_attributes_no_AWS + ) + check = SNSPublicAccessCheck() + results = check.execute() + for result in results: + if "MyTopic" in result["Id"]: assert result["RecordState"] == "ARCHIVED" else: assert False