diff --git a/docs/content/en/integrations/parsers/file/aws_prowler_v3.md b/docs/content/en/integrations/parsers/file/aws_prowler_v3.md deleted file mode 100644 index 17dcf9698ae..00000000000 --- a/docs/content/en/integrations/parsers/file/aws_prowler_v3.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: "AWS Prowler V3" -toc_hide: true ---- - -### File Types -DefectDojo parser accepts a .json file. Please note: earlier versions of AWS Prowler create output data in a different format. See our other documentation if you are using an earlier version of AWS Prowler: https://documentation.defectdojo.com/integrations/parsers/file/aws_prowler/ - -JSON reports can be created from the [AWS Prowler V3 CLI](https://docs.prowler.cloud/en/latest/tutorials/reporting/#json) using the following command: `prowler -M json` - -### Acceptable JSON Format -Parser expects an array of assessments. All properties are strings and are required by the parser. - -~~~ - -[ - { - "AssessmentStartTime": "example_timestamp", - "FindingUniqueId": "example_uniqueIdFromTool", - "Provider": "example_provider", - "CheckID": "acm_certificates_expiration_check", - "CheckTitle": "Check if ACM Certificates are about to expire in specific days or less", - "CheckType": [ - "Example ASFF-Compliant Finding Type" - ], - "ServiceName": "example_awsServiceName", - "SubServiceName": "", - "Status": "FAIL", - "StatusExtended": "Example status description", - "Severity": "example_severity", - "ResourceType": "AwsCertificateManagerCertificate", - "ResourceDetails": "", - "Description": "Example general test description.", - "Risk": "Example test impact description.", - "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html", - "Remediation": { - "Code": { - "NativeIaC": "", - "Terraform": "", - "CLI": "", - "Other": "" - }, - "Recommendation": { - "Text": "Example recommendation.", - "Url": "https://docs.aws.amazon.com/config/latest/developerguide/example_related_documentation.html" - } - }, - "Compliance": { - "GDPR": [ - "article_32" - ], - ... - }, - "Categories": [], - "DependsOn": [], - "RelatedTo": [], - "Notes": "", - "Profile": null, - "AccountId": "example_accountId", - "OrganizationsInfo": null, - "Region": "example_region", - "ResourceId": "example.resource.id.com", - "ResourceArn": "arn:aws:acm:us-east-1:999999999999:certificate/ffffffff-0000-0000-0000-000000000000", - "ResourceTags": {} - } - ... -] - -~~~ - -### Sample Scan Data -Unit tests of AWS Prowler V3 JSON can be found at https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/aws_prowler_v3. \ No newline at end of file diff --git a/docs/content/en/integrations/parsers/file/aws_prowler_v3plus.md b/docs/content/en/integrations/parsers/file/aws_prowler_v3plus.md new file mode 100644 index 00000000000..687d9faf586 --- /dev/null +++ b/docs/content/en/integrations/parsers/file/aws_prowler_v3plus.md @@ -0,0 +1,163 @@ +--- +title: "AWS Prowler V3" +toc_hide: true +--- + +### File Types +DefectDojo parser accepts a native `json` file produced by prowler v3 with file extension `.json` or a `ocsf-json` file produced by prowler v4 with file extension `.ocsf.json`. +Please note: earlier versions of AWS Prowler create output data in a different format. See our other [prowler parser documentation](https://documentation.defectdojo.com/integrations/parsers/file/aws_prowler/) if you are using an earlier version of AWS Prowler. + +JSON reports can be created from the [AWS Prowler v3 CLI](https://docs.prowler.com/projects/prowler-open-source/en/v3/tutorials/reporting/#json) using the following command: `prowler -M json` + +JSON-OCSF reports can be created from the [AWS Prowler v4 CLI](https://docs.prowler.cloud/en/latest/tutorials/reporting/#json) using the following command: `prowler -M json-ocsf` + + +### Acceptable Prowler v3 JSON format +Parser expects an array of assessments. All properties are strings and are required by the parser. + +~~~ + +[ + { + "AssessmentStartTime": "example_timestamp", + "FindingUniqueId": "example_uniqueIdFromTool", + "Provider": "example_provider", + "CheckID": "acm_certificates_expiration_check", + "CheckTitle": "Check if ACM Certificates are about to expire in specific days or less", + "CheckType": [ + "Example ASFF-Compliant Finding Type" + ], + "ServiceName": "example_awsServiceName", + "SubServiceName": "", + "Status": "FAIL", + "StatusExtended": "Example status description", + "Severity": "example_severity", + "ResourceType": "AwsCertificateManagerCertificate", + "ResourceDetails": "", + "Description": "Example general test description.", + "Risk": "Example test impact description.", + "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html", + "Remediation": { + "Code": { + "NativeIaC": "", + "Terraform": "", + "CLI": "", + "Other": "" + }, + "Recommendation": { + "Text": "Example recommendation.", + "Url": "https://docs.aws.amazon.com/config/latest/developerguide/example_related_documentation.html" + } + }, + "Compliance": { + "GDPR": [ + "article_32" + ], + ... + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "", + "Profile": null, + "AccountId": "example_accountId", + "OrganizationsInfo": null, + "Region": "example_region", + "ResourceId": "example.resource.id.com", + "ResourceArn": "arn:aws:acm:us-east-1:999999999999:certificate/ffffffff-0000-0000-0000-000000000000", + "ResourceTags": {} + } + ... +] + +~~~ + +### Acceptable Prowler v4 JSON-OCSF format +The parser expects an array of assessments. All properties are strings and are required by the parser. + +~~~ +[{ + "metadata": { + "event_code": "iam_role_administratoraccess_policy_permissive_trust_relationship", + "product": { + "name": "Prowler", + "vendor_name": "Prowler", + "version": "4.2.1" + }, + "version": "1.2.0" + }, + "severity_id": 4, + "severity": "High", + "status": "Suppressed", + "status_code": "FAIL", + "status_detail": "IAM Role myAdministratorExecutionRole has AdministratorAccess policy attached that has too permissive trust relationship.", + "status_id": 3, + "unmapped": { + "check_type": "", + "related_url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator", + "categories": "trustboundaries", + "depends_on": "", + "related_to": "", + "notes": "CAF Security Epic: IAM", + "compliance": {} + }, + "activity_name": "Create", + "activity_id": 1, + "finding_info": { + "created_time": "2024-06-03T14:15:19.382075", + "desc": "Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship", + "product_uid": "prowler", + "title": "Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship", + "uid": "prowler-aws-iam_role_administratoraccess_policy_permissive_trust_relationship-123456789012-us-east-1-myAdministratorExecutionRole" + }, + "resources": [ + { + "cloud_partition": "aws", + "region": "us-east-1", + "data": { + "details": "" + }, + "group": { + "name": "iam" + }, + "labels": [], + "name": "myAdministratorExecutionRole", + "type": "AwsIamRole", + "uid": "arn:aws:iam::123456789012:role/myAdministratorExecutionRole" + } + ], + "category_name": "Findings", + "category_uid": 2, + "class_name": "DetectionFinding", + "class_uid": 2004, + "cloud": { + "account": { + "name": "", + "type": "AWS_Account", + "type_id": 10, + "uid": "123456789012", + "labels": [] + }, + "org": { + "name": "", + "uid": "" + }, + "provider": "aws", + "region": "us-east-1" + }, + "event_time": "2024-06-03T14:15:19.382075", + "remediation": { + "desc": "Apply the principle of least privilege. Instead of AdministratorAccess, assign only the permissions necessary for specific roles and tasks. Create custom IAM policies with minimal permissions based on the principle of least privilege. If a role really needs AdministratorAccess, the trust relationship must be well defined to restrict it usage only to the Principal, Action, Audience and Subject intended for it.", + "references": [ + "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege" + ] + }, + "risk_details": "The AWS-managed AdministratorAccess policy grants all actions for all AWS services and for all resources in the account and as such exposes the customer to a significant data leakage threat. It is therefore particularly important that the trust relationship is well defined to restrict it usage only to the Principal, Action, Audience and Subject intended for it.", + "type_uid": 200401, + "type_name": "Create" +}] + +~~~ + +### Sample Scan Data +Unit tests of AWS Prowler v3 JSON and Prowler v4 JSON-OCSF can be found at https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/aws_prowler_v3. \ No newline at end of file diff --git a/dojo/tools/aws_prowler_v3/__init__.py b/dojo/tools/aws_prowler_v3plus/__init__.py similarity index 100% rename from dojo/tools/aws_prowler_v3/__init__.py rename to dojo/tools/aws_prowler_v3plus/__init__.py diff --git a/dojo/tools/aws_prowler_v3plus/parser.py b/dojo/tools/aws_prowler_v3plus/parser.py new file mode 100644 index 00000000000..8e62047ac86 --- /dev/null +++ b/dojo/tools/aws_prowler_v3plus/parser.py @@ -0,0 +1,24 @@ +from dojo.tools.aws_prowler_v3plus.prowler_v3 import AWSProwlerV3Parser +from dojo.tools.aws_prowler_v3plus.prowler_v4 import AWSProwlerV4Parser + + +class AWSProwlerV3plusParser: + SCAN_TYPE = ["AWS Prowler V3"] + + def get_scan_types(self): + return AWSProwlerV3plusParser.SCAN_TYPE + + def get_label_for_scan_types(self, scan_type): + return AWSProwlerV3plusParser.SCAN_TYPE[0] + + def get_description_for_scan_types(self, scan_type): + return "Exports from AWS Prowler v3 in JSON format or from Prowler v4 in OCSF-JSON format." + + def get_findings(self, file, test): + if file.name.lower().endswith('.ocsf.json'): + return AWSProwlerV4Parser().process_ocsf_json(file, test) + elif file.name.lower().endswith('.json'): + return AWSProwlerV3Parser().process_json(file, test) + else: + msg = 'Unknown file format' + raise ValueError(msg) diff --git a/dojo/tools/aws_prowler_v3/parser.py b/dojo/tools/aws_prowler_v3plus/prowler_v3.py similarity index 84% rename from dojo/tools/aws_prowler_v3/parser.py rename to dojo/tools/aws_prowler_v3plus/prowler_v3.py index 60f7a5dc7e8..cce0472b67d 100644 --- a/dojo/tools/aws_prowler_v3/parser.py +++ b/dojo/tools/aws_prowler_v3plus/prowler_v3.py @@ -1,4 +1,3 @@ - import hashlib import json import textwrap @@ -8,24 +7,6 @@ class AWSProwlerV3Parser: - SCAN_TYPE = ["AWS Prowler V3"] - - def get_scan_types(self): - return AWSProwlerV3Parser.SCAN_TYPE - - def get_label_for_scan_types(self, scan_type): - return AWSProwlerV3Parser.SCAN_TYPE[0] - - def get_description_for_scan_types(self, scan_type): - return "Export of AWS Prowler JSON V3 format." - - def get_findings(self, file, test): - if file.name.lower().endswith('.json'): - return self.process_json(file, test) - else: - msg = 'Unknown file format' - raise ValueError(msg) - def process_json(self, file, test): dupes = {} @@ -96,9 +77,3 @@ def process_json(self, file, test): dupes[dupe_key] = find return list(dupes.values()) - - def formatview(self, depth): - if depth > 1: - return "* " - else: - return "" diff --git a/dojo/tools/aws_prowler_v3plus/prowler_v4.py b/dojo/tools/aws_prowler_v3plus/prowler_v4.py new file mode 100644 index 00000000000..ac3c4a99e6c --- /dev/null +++ b/dojo/tools/aws_prowler_v3plus/prowler_v4.py @@ -0,0 +1,83 @@ +import hashlib +import json +import textwrap +from datetime import date + +from dojo.models import Finding + + +class AWSProwlerV4Parser: + def process_ocsf_json(self, file, test): + dupes = {} + + data = json.load(file) + # mapping of json fields between Prowler v3 and v4: + # https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/reporting/#json + for deserialized in data: + + status = deserialized.get('status_code') + if status.upper() != 'FAIL': + continue + + account_id = deserialized.get('cloud', {}).get('account', {}).get("uid", '') + region = deserialized.get('resources', [{}])[0].get('region', '') + provider = deserialized.get('cloud', {}).get('provider', '') + compliance = '' + compliance_field = deserialized.get('unmapped', {}).get("compliance", {}) + if compliance_field: + compliance = ' | '.join([f"{key}:{','.join(value)}" for key, value in compliance_field.items()]) + result_extended = deserialized.get('status_detail') + general_description = deserialized.get('finding_info', {}).get('desc', '') + asff_compliance_type = deserialized.get('unmapped', {}).get('check_type', '') + severity = deserialized.get('severity', 'Info').capitalize() + aws_service_name = deserialized.get('resources', [{}])[0].get('group', {}).get('name', '') + impact = deserialized.get('risk_details') + mitigation = deserialized.get('remediation', {}).get("desc", '') + documentation = deserialized.get('remediation', {}).get("references", '') + documentation = str(documentation) + "\n" + str(deserialized.get('unmapped', {}).get('related_url', '')) + security_domain = deserialized.get('resources', [{}])[0].get('type', '') + timestamp = deserialized.get("event_time") + resource_arn = deserialized.get('resources', [{}])[0].get('uid', '') + resource_id = deserialized.get('resources', [{}])[0].get('name', '') + unique_id_from_tool = deserialized.get('finding_info', {}).get('uid', '') + if not resource_arn or resource_arn == "": + component_name = str(provider) + "-" + str(account_id) + "-" + str(region) + "-" + str(resource_id) + else: + component_name = resource_arn + + description = "**Issue:** " + str(result_extended) + \ + "\n**Description:** " + str(general_description) + \ + "\n**AWS Account:** " + str(account_id) + \ + "\n**Region:** " + str(region) + \ + "\n**AWS Service:** " + str(aws_service_name) + \ + "\n**Security Domain:** " + str(security_domain) + \ + "\n**Compliance:** " + str(compliance) + \ + "\n**ASFF Compliance Type:** " + str(asff_compliance_type) + + # improving key to get duplicates + dupe_key = hashlib.sha256(unique_id_from_tool.encode('utf-8')).hexdigest() + if dupe_key in dupes: + find = dupes[dupe_key] + if description is not None: + find.description += description + "\n\n" + find.nb_occurences += 1 + else: + find = Finding( + title=textwrap.shorten(result_extended, 150), + cwe=1032, # Security Configuration Weaknesses, would like to fine tune + test=test, + description=description, + component_name=component_name, + unique_id_from_tool=unique_id_from_tool, + severity=severity, + references=documentation, + date=date.fromisoformat(timestamp[:10]), + static_finding=True, + dynamic_finding=False, + nb_occurences=1, + mitigation=mitigation, + impact=impact, + ) + dupes[dupe_key] = find + + return list(dupes.values()) diff --git a/unittests/scans/aws_prowler_v3/many_vuln.json b/unittests/scans/aws_prowler_v3plus/many_vuln.json similarity index 100% rename from unittests/scans/aws_prowler_v3/many_vuln.json rename to unittests/scans/aws_prowler_v3plus/many_vuln.json diff --git a/unittests/scans/aws_prowler_v3plus/many_vuln.ocsf.json b/unittests/scans/aws_prowler_v3plus/many_vuln.ocsf.json new file mode 100644 index 00000000000..e0f563c2a05 --- /dev/null +++ b/unittests/scans/aws_prowler_v3plus/many_vuln.ocsf.json @@ -0,0 +1,247 @@ +[{ + "metadata": { + "event_code": "iam_role_administratoraccess_policy_permissive_trust_relationship", + "product": { + "name": "Prowler", + "vendor_name": "Prowler", + "version": "4.2.1" + }, + "version": "1.2.0" + }, + "severity_id": 4, + "severity": "High", + "status": "Suppressed", + "status_code": "FAIL", + "status_detail": "IAM Role myAdministratorExecutionRole has AdministratorAccess policy attached that has too permissive trust relationship.", + "status_id": 3, + "unmapped": { + "check_type": "", + "related_url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator", + "categories": "trustboundaries", + "depends_on": "", + "related_to": "", + "notes": "CAF Security Epic: IAM", + "compliance": {} + }, + "activity_name": "Create", + "activity_id": 1, + "finding_info": { + "created_time": "2024-06-03T14:15:19.382075", + "desc": "Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship", + "product_uid": "prowler", + "title": "Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship", + "uid": "prowler-aws-iam_role_administratoraccess_policy_permissive_trust_relationship-123456789012-us-east-1-myAdministratorExecutionRole" + }, + "resources": [ + { + "cloud_partition": "aws", + "region": "us-east-1", + "data": { + "details": "" + }, + "group": { + "name": "iam" + }, + "labels": [], + "name": "myAdministratorExecutionRole", + "type": "AwsIamRole", + "uid": "arn:aws:iam::123456789012:role/myAdministratorExecutionRole" + } + ], + "category_name": "Findings", + "category_uid": 2, + "class_name": "DetectionFinding", + "class_uid": 2004, + "cloud": { + "account": { + "name": "", + "type": "AWS_Account", + "type_id": 10, + "uid": "123456789012", + "labels": [] + }, + "org": { + "name": "", + "uid": "" + }, + "provider": "aws", + "region": "us-east-1" + }, + "event_time": "2024-06-03T14:15:19.382075", + "remediation": { + "desc": "Apply the principle of least privilege. Instead of AdministratorAccess, assign only the permissions necessary for specific roles and tasks. Create custom IAM policies with minimal permissions based on the principle of least privilege. If a role really needs AdministratorAccess, the trust relationship must be well defined to restrict it usage only to the Principal, Action, Audience and Subject intended for it.", + "references": [ + "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege" + ] + }, + "risk_details": "The AWS-managed AdministratorAccess policy grants all actions for all AWS services and for all resources in the account and as such exposes the customer to a significant data leakage threat. It is therefore particularly important that the trust relationship is well defined to restrict it usage only to the Principal, Action, Audience and Subject intended for it.", + "type_uid": 200401, + "type_name": "Create" +},{ + "metadata": { + "event_code": "iam_role_cross_account_readonlyaccess_policy", + "product": { + "name": "Prowler", + "vendor_name": "Prowler", + "version": "4.2.1" + }, + "version": "1.2.0" + }, + "severity_id": 4, + "severity": "High", + "status": "Suppressed", + "status_code": "FAIL", + "status_detail": "IAM Role AuditRole gives cross account read-only access.", + "status_id": 3, + "unmapped": { + "check_type": "", + "related_url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#awsmp_readonlyaccess", + "categories": "trustboundaries", + "depends_on": "", + "related_to": "", + "notes": "CAF Security Epic: IAM", + "compliance": { + "MITRE-ATTACK": [ + "T1078" + ], + "AWS-Foundational-Technical-Review": [ + "IAM-0012" + ] + } + }, + "activity_name": "Create", + "activity_id": 1, + "finding_info": { + "created_time": "2024-06-03T14:15:19.382075", + "desc": "Ensure IAM Roles do not have ReadOnlyAccess access for external AWS accounts", + "product_uid": "prowler", + "title": "Ensure IAM Roles do not have ReadOnlyAccess access for external AWS accounts", + "uid": "prowler-aws-iam_role_cross_account_readonlyaccess_policy-123456789012-us-east-1-AuditRole" + }, + "resources": [ + { + "cloud_partition": "aws", + "region": "us-east-1", + "data": { + "details": "" + }, + "group": { + "name": "iam" + }, + "labels": [ + "some-label=some value" + ], + "name": "AuditRole", + "type": "AwsIamRole", + "uid": "arn:aws:iam::123456789012:role/AuditRole" + } + ], + "category_name": "Findings", + "category_uid": 2, + "class_name": "DetectionFinding", + "class_uid": 2004, + "cloud": { + "account": { + "name": "", + "type": "AWS_Account", + "type_id": 10, + "uid": "123456789012", + "labels": [] + }, + "org": { + "name": "", + "uid": "" + }, + "provider": "aws", + "region": "us-east-1" + }, + "event_time": "2024-06-03T14:15:19.382075", + "remediation": { + "desc": "Remove the AWS-managed ReadOnlyAccess policy from all roles that have a trust policy, including third-party cloud accounts, or remove third-party cloud accounts from the trust policy of all roles that need the ReadOnlyAccess policy.", + "references": [ + "https://docs.securestate.vmware.com/rule-docs/aws-iam-role-cross-account-readonlyaccess-policy" + ] + }, + "risk_details": "The AWS-managed ReadOnlyAccess policy is highly potent and exposes the customer to a significant data leakage threat. It should be granted very conservatively. For granting access to 3rd party vendors, consider using alternative managed policies, such as ViewOnlyAccess or SecurityAudit.", + "type_uid": 200401, + "type_name": "Create" +},{ + "metadata": { + "event_code": "iam_role_permissive_trust_relationship", + "product": { + "name": "Prowler", + "vendor_name": "Prowler", + "version": "4.2.1" + }, + "version": "1.2.0" + }, + "severity_id": 4, + "severity": "High", + "status": "Suppressed", + "status_code": "FAIL", + "status_detail": "IAM Role CrossAccountResourceAccessRole has permissive trust relationship to other accounts", + "status_id": 3, + "unmapped": { + "check_type": "", + "related_url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-accounts", + "categories": "trustboundaries", + "depends_on": "", + "related_to": "", + "notes": "CAF Security Epic: IAM", + "compliance": {} + }, + "activity_name": "Create", + "activity_id": 1, + "finding_info": { + "created_time": "2024-06-03T14:15:19.382075", + "desc": "Ensure IAM Roles do not allow assume role from any role of a cross account", + "product_uid": "prowler", + "title": "Ensure IAM Roles do not allow assume role from any role of a cross account", + "uid": "prowler-aws-iam_role_permissive_trust_relationship-123456789012-us-east-1-CrossAccountResourceAccessRole" + }, + "resources": [ + { + "cloud_partition": "aws", + "region": "us-east-1", + "data": { + "details": "" + }, + "group": { + "name": "iam" + }, + "labels": [], + "name": "CrossAccountResourceAccessRole", + "type": "AwsIamRole", + "uid": "arn:aws:iam::123456789012:role/CrossAccountResourceAccessRole" + } + ], + "category_name": "Findings", + "category_uid": 2, + "class_name": "DetectionFinding", + "class_uid": 2004, + "cloud": { + "account": { + "name": "", + "type": "AWS_Account", + "type_id": 10, + "uid": "123456789012", + "labels": [] + }, + "org": { + "name": "", + "uid": "" + }, + "provider": "aws", + "region": "us-east-1" + }, + "event_time": "2024-06-03T14:15:19.382075", + "remediation": { + "desc": "Ensure IAM Roles do not allow assume role from any role of a cross account but only from specific roles of specific accounts.", + "references": [ + "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-roles" + ] + }, + "risk_details": "If an IAM role allows assume role from any role of a cross account, it can lead to privilege escalation.", + "type_uid": 200401, + "type_name": "Create" +}] \ No newline at end of file diff --git a/unittests/scans/aws_prowler_v3/no_vuln.json b/unittests/scans/aws_prowler_v3plus/no_vuln.json similarity index 100% rename from unittests/scans/aws_prowler_v3/no_vuln.json rename to unittests/scans/aws_prowler_v3plus/no_vuln.json diff --git a/unittests/scans/aws_prowler_v3plus/no_vuln.ocsf.json b/unittests/scans/aws_prowler_v3plus/no_vuln.ocsf.json new file mode 100644 index 00000000000..0637a088a01 --- /dev/null +++ b/unittests/scans/aws_prowler_v3plus/no_vuln.ocsf.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/unittests/scans/aws_prowler_v3/one_vuln.json b/unittests/scans/aws_prowler_v3plus/one_vuln.json similarity index 100% rename from unittests/scans/aws_prowler_v3/one_vuln.json rename to unittests/scans/aws_prowler_v3plus/one_vuln.json diff --git a/unittests/scans/aws_prowler_v3plus/one_vuln.ocsf.json b/unittests/scans/aws_prowler_v3plus/one_vuln.ocsf.json new file mode 100644 index 00000000000..5e45f2077e3 --- /dev/null +++ b/unittests/scans/aws_prowler_v3plus/one_vuln.ocsf.json @@ -0,0 +1,80 @@ +[{ + "metadata": { + "event_code": "iam_role_administratoraccess_policy_permissive_trust_relationship", + "product": { + "name": "Prowler", + "vendor_name": "Prowler", + "version": "4.2.1" + }, + "version": "1.2.0" + }, + "severity_id": 4, + "severity": "High", + "status": "Suppressed", + "status_code": "FAIL", + "status_detail": "IAM Role myAdministratorExecutionRole has AdministratorAccess policy attached that has too permissive trust relationship.", + "status_id": 3, + "unmapped": { + "check_type": "", + "related_url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator", + "categories": "trustboundaries", + "depends_on": "", + "related_to": "", + "notes": "CAF Security Epic: IAM", + "compliance": {} + }, + "activity_name": "Create", + "activity_id": 1, + "finding_info": { + "created_time": "2024-06-03T14:15:19.382075", + "desc": "Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship", + "product_uid": "prowler", + "title": "Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship", + "uid": "prowler-aws-iam_role_administratoraccess_policy_permissive_trust_relationship-123456789012-us-east-1-myAdministratorExecutionRole" + }, + "resources": [ + { + "cloud_partition": "aws", + "region": "us-east-1", + "data": { + "details": "" + }, + "group": { + "name": "iam" + }, + "labels": [], + "name": "myAdministratorExecutionRole", + "type": "AwsIamRole", + "uid": "arn:aws:iam::123456789012:role/myAdministratorExecutionRole" + } + ], + "category_name": "Findings", + "category_uid": 2, + "class_name": "DetectionFinding", + "class_uid": 2004, + "cloud": { + "account": { + "name": "", + "type": "AWS_Account", + "type_id": 10, + "uid": "123456789012", + "labels": [] + }, + "org": { + "name": "", + "uid": "" + }, + "provider": "aws", + "region": "us-east-1" + }, + "event_time": "2024-06-03T14:15:19.382075", + "remediation": { + "desc": "Apply the principle of least privilege. Instead of AdministratorAccess, assign only the permissions necessary for specific roles and tasks. Create custom IAM policies with minimal permissions based on the principle of least privilege. If a role really needs AdministratorAccess, the trust relationship must be well defined to restrict it usage only to the Principal, Action, Audience and Subject intended for it.", + "references": [ + "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege" + ] + }, + "risk_details": "The AWS-managed AdministratorAccess policy grants all actions for all AWS services and for all resources in the account and as such exposes the customer to a significant data leakage threat. It is therefore particularly important that the trust relationship is well defined to restrict it usage only to the Principal, Action, Audience and Subject intended for it.", + "type_uid": 200401, + "type_name": "Create" +}] \ No newline at end of file diff --git a/unittests/tools/test_aws_prowler_v3_parser.py b/unittests/tools/test_aws_prowler_v3_parser.py deleted file mode 100644 index c92ff3f9226..00000000000 --- a/unittests/tools/test_aws_prowler_v3_parser.py +++ /dev/null @@ -1,39 +0,0 @@ -from dojo.models import Test -from dojo.tools.aws_prowler_v3.parser import AWSProwlerV3Parser -from unittests.dojo_test_case import DojoTestCase - - -class TestAwsProwlerV3Parser(DojoTestCase): - def setup(self, testfile): - parser = AWSProwlerV3Parser() - findings = parser.get_findings(testfile, Test()) - testfile.close() - return findings - - def test_aws_prowler_parser_with_no_vuln_has_no_findings_json(self): - findings = self.setup( - open("unittests/scans/aws_prowler_v3/no_vuln.json")) - self.assertEqual(0, len(findings)) - - def test_aws_prowler_parser_with_critical_vuln_has_one_findings_json(self): - findings = self.setup( - open("unittests/scans/aws_prowler_v3/one_vuln.json")) - self.assertEqual(1, len(findings)) - self.assertEqual("prowler-aws-acm_certificates_expiration_check-999999999999-us-east-1-api.sandbox.partner.teste.com", findings[0].unique_id_from_tool) - self.assertIn('Check if ACM Certificates are about to expire in specific days or less', findings[0].description) - self.assertEqual("arn:aws:acm:us-east-1:999999999999:certificate/ffffffff-0000-0000-0000-000000000000", findings[0].component_name) - self.assertIn('https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html', findings[0].references) - - def test_aws_prowler_parser_with_many_vuln_has_many_findings_json(self): - findings = self.setup( - open("unittests/scans/aws_prowler_v3/many_vuln.json")) - self.assertEqual(3, len(findings)) - with self.subTest(i=0): - self.assertEqual("prowler-aws-acm_certificates_expiration_check-999999999999-us-east-1-api.teste.teste.com", findings[0].unique_id_from_tool) - self.assertIn('Check if ACM Certificates are about to expire in specific days or less', findings[0].description) - with self.subTest(i=1): - self.assertEqual("prowler-aws-accessanalyzer_enabled-999999999999-us-east-1-999999999999", findings[1].unique_id_from_tool) - self.assertIn('Check if IAM Access Analyzer is enabled', findings[1].description) - with self.subTest(i=3): - self.assertEqual("prowler-aws-account_maintain_current_contact_details-999999999999-us-east-1-999999999999", findings[2].unique_id_from_tool) - self.assertIn('Maintain current contact details.', findings[2].description) diff --git a/unittests/tools/test_aws_prowler_v3plus_parser.py b/unittests/tools/test_aws_prowler_v3plus_parser.py new file mode 100644 index 00000000000..5096c6275d0 --- /dev/null +++ b/unittests/tools/test_aws_prowler_v3plus_parser.py @@ -0,0 +1,67 @@ +from dojo.models import Test +from dojo.tools.aws_prowler_v3plus.parser import AWSProwlerV3plusParser +from unittests.dojo_test_case import DojoTestCase + + +class TestAwsProwlerV3plusParser(DojoTestCase): + def setup(self, testfile): + parser = AWSProwlerV3plusParser() + findings = parser.get_findings(testfile, Test()) + testfile.close() + return findings + + def test_aws_prowler_parser_with_no_vuln_has_no_findings_json(self): + findings = self.setup( + open("unittests/scans/aws_prowler_v3plus/no_vuln.json")) + self.assertEqual(0, len(findings)) + + def test_aws_prowler_parser_with_critical_vuln_has_one_findings_json(self): + findings = self.setup( + open("unittests/scans/aws_prowler_v3plus/one_vuln.json")) + self.assertEqual(1, len(findings)) + self.assertEqual("prowler-aws-acm_certificates_expiration_check-999999999999-us-east-1-api.sandbox.partner.teste.com", findings[0].unique_id_from_tool) + self.assertIn('Check if ACM Certificates are about to expire in specific days or less', findings[0].description) + self.assertEqual("arn:aws:acm:us-east-1:999999999999:certificate/ffffffff-0000-0000-0000-000000000000", findings[0].component_name) + self.assertIn('https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html', findings[0].references) + + def test_aws_prowler_parser_with_many_vuln_has_many_findings_json(self): + findings = self.setup( + open("unittests/scans/aws_prowler_v3plus/many_vuln.json")) + self.assertEqual(3, len(findings)) + with self.subTest(i=0): + self.assertEqual("prowler-aws-acm_certificates_expiration_check-999999999999-us-east-1-api.teste.teste.com", findings[0].unique_id_from_tool) + self.assertIn('Check if ACM Certificates are about to expire in specific days or less', findings[0].description) + with self.subTest(i=1): + self.assertEqual("prowler-aws-accessanalyzer_enabled-999999999999-us-east-1-999999999999", findings[1].unique_id_from_tool) + self.assertIn('Check if IAM Access Analyzer is enabled', findings[1].description) + with self.subTest(i=3): + self.assertEqual("prowler-aws-account_maintain_current_contact_details-999999999999-us-east-1-999999999999", findings[2].unique_id_from_tool) + self.assertIn('Maintain current contact details.', findings[2].description) + + def test_aws_prowler_parser_with_no_vuln_has_no_findings_ocsf_json(self): + findings = self.setup( + open("unittests/scans/aws_prowler_v3plus/no_vuln.ocsf.json")) + self.assertEqual(0, len(findings)) + + def test_aws_prowler_parser_with_critical_vuln_has_one_findings_ocsf_json(self): + findings = self.setup( + open("unittests/scans/aws_prowler_v3plus/one_vuln.ocsf.json")) + self.assertEqual(1, len(findings)) + self.assertEqual("prowler-aws-iam_role_administratoraccess_policy_permissive_trust_relationship-123456789012-us-east-1-myAdministratorExecutionRole", findings[0].unique_id_from_tool) + self.assertIn('Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship', findings[0].description) + self.assertEqual("arn:aws:iam::123456789012:role/myAdministratorExecutionRole", findings[0].component_name) + self.assertIn('https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege', findings[0].references) + + def test_aws_prowler_parser_with_many_vuln_has_many_findings_ocsf_json(self): + findings = self.setup( + open("unittests/scans/aws_prowler_v3plus/many_vuln.ocsf.json")) + self.assertEqual(3, len(findings)) + with self.subTest(i=0): + self.assertEqual("prowler-aws-iam_role_administratoraccess_policy_permissive_trust_relationship-123456789012-us-east-1-myAdministratorExecutionRole", findings[0].unique_id_from_tool) + self.assertIn('Ensure IAM Roles with attached AdministratorAccess policy have a well defined trust relationship', findings[0].description) + with self.subTest(i=1): + self.assertEqual("prowler-aws-iam_role_cross_account_readonlyaccess_policy-123456789012-us-east-1-AuditRole", findings[1].unique_id_from_tool) + self.assertIn('Ensure IAM Roles do not have ReadOnlyAccess access for external AWS accounts', findings[1].description) + with self.subTest(i=3): + self.assertEqual("prowler-aws-iam_role_permissive_trust_relationship-123456789012-us-east-1-CrossAccountResourceAccessRole", findings[2].unique_id_from_tool) + self.assertIn('Ensure IAM Roles do not allow assume role from any role of a cross account', findings[2].description)