diff --git a/prowler/lib/outputs/json.py b/prowler/lib/outputs/json.py index 33183738..0280bb42 100644 --- a/prowler/lib/outputs/json.py +++ b/prowler/lib/outputs/json.py @@ -55,7 +55,12 @@ def fill_json_asff(finding_output, audit_info, finding, output_options): Label=finding.check_metadata.Severity.upper() ) finding_output.Title = finding.check_metadata.CheckTitle - finding_output.Description = finding.status_extended + # Description should NOT be longer than 1024 characters + finding_output.Description = ( + (finding.status_extended[:1000] + "...") + if len(finding.status_extended) > 1000 + else finding.status_extended + ) finding_output.Resources = [ Resource( Id=finding.resource_arn, @@ -69,11 +74,14 @@ def fill_json_asff(finding_output, audit_info, finding, output_options): associated_standards = [] check_compliance = get_check_compliance(finding, "aws", output_options) for key, value in check_compliance.items(): - associated_standards.append({"StandardsId": key}) - item = f"{key} {' '.join(value)}" - if len(item) > 64: - item = item[0:63] - compliance_summary.append(item) + if ( + len(associated_standards) < 20 + ): # AssociatedStandards should NOT have more than 20 items + associated_standards.append({"StandardsId": key}) + item = f"{key} {' '.join(value)}" + if len(item) > 64: + item = item[0:63] + compliance_summary.append(item) # Ensures finding_status matches allowed values in ASFF finding_status = generate_json_asff_status(finding.status) diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_field_level_encryption_enabled/cloudfront_distributions_field_level_encryption_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_field_level_encryption_enabled/cloudfront_distributions_field_level_encryption_enabled.metadata.json index ef5e1aa7..79c7c7cc 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_field_level_encryption_enabled/cloudfront_distributions_field_level_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_field_level_encryption_enabled/cloudfront_distributions_field_level_encryption_enabled.metadata.json @@ -2,9 +2,7 @@ "Provider": "aws", "CheckID": "cloudfront_distributions_field_level_encryption_enabled", "CheckTitle": "Check if CloudFront distributions have Field Level Encryption enabled.", - "CheckType": [ - "" - ], + "CheckType": [], "ServiceName": "cloudfront", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:cloudfront:region:account-id:distribution/resource-id", diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json index 6170a520..111a7062 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json @@ -2,9 +2,7 @@ "Provider": "aws", "CheckID": "cloudfront_distributions_geo_restrictions_enabled", "CheckTitle": "Check if Geo restrictions are enabled in CloudFront distributions.", - "CheckType": [ - "" - ], + "CheckType": [], "ServiceName": "cloudfront", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:cloudfront:region:account-id:distribution/resource-id", diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json index 5e4d2327..12d9d898 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json @@ -2,9 +2,7 @@ "Provider": "aws", "CheckID": "cloudfront_distributions_https_enabled", "CheckTitle": "Check if CloudFront distributions are set to HTTPS.", - "CheckType": [ - "" - ], + "CheckType": [], "ServiceName": "cloudfront", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:cloudfront:region:account-id:distribution/resource-id", diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json index ba58ff92..e368af17 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json @@ -2,9 +2,7 @@ "Provider": "aws", "CheckID": "cloudfront_distributions_logging_enabled", "CheckTitle": "Check if CloudFront distributions have logging enabled.", - "CheckType": [ - "" - ], + "CheckType": [], "ServiceName": "cloudfront", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:cloudfront:region:account-id:distribution/resource-id", diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json index 507739ed..653b892a 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json @@ -2,9 +2,7 @@ "Provider": "aws", "CheckID": "cloudfront_distributions_using_deprecated_ssl_protocols", "CheckTitle": "Check if CloudFront distributions are using deprecated SSL protocols.", - "CheckType": [ - "" - ], + "CheckType": [], "ServiceName": "cloudfront", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:cloudfront:region:account-id:distribution/resource-id", diff --git a/prowler/providers/aws/services/rds/rds_instance_deprecated_engine_version/rds_instance_deprecated_engine_version.metadata.json b/prowler/providers/aws/services/rds/rds_instance_deprecated_engine_version/rds_instance_deprecated_engine_version.metadata.json index affb9836..73b43ceb 100644 --- a/prowler/providers/aws/services/rds/rds_instance_deprecated_engine_version/rds_instance_deprecated_engine_version.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_deprecated_engine_version/rds_instance_deprecated_engine_version.metadata.json @@ -19,7 +19,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "", + "Text": "Ensure all the RDS instances are using a supported engine version", "Url": "https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html" } }, diff --git a/tests/lib/outputs/outputs_test.py b/tests/lib/outputs/outputs_test.py index b28c74e8..21b6ba9e 100644 --- a/tests/lib/outputs/outputs_test.py +++ b/tests/lib/outputs/outputs_test.py @@ -6,6 +6,7 @@ import boto3 import botocore import pytest from colorama import Fore +from mock import patch from moto import mock_s3 from prowler.config.config import ( @@ -573,6 +574,367 @@ class Test_Outputs: fill_json_asff(input, input_audit_info, finding, output_options) == expected ) + def test_fill_json_asff_with_long_description(self): + input_audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=None, + audited_account=AWS_ACCOUNT_ID, + audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_ID}:root", + audited_identity_arn="test-arn", + audited_user_id="test", + audited_partition="aws", + profile="default", + profile_region="eu-west-1", + credentials=None, + assumed_role_info=None, + audited_regions=["eu-west-2", "eu-west-1"], + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + ) + finding = Check_Report( + load_check_metadata( + f"{path.dirname(path.realpath(__file__))}/fixtures/metadata.json" + ).json() + ) + + # Empty the Remediation.Recomendation.URL + finding.check_metadata.Remediation.Recommendation.Url = "" + + finding.resource_details = "Test resource details" + finding.resource_id = "test-resource" + finding.resource_arn = "test-arn" + finding.region = "eu-west-1" + finding.status = "PASS" + finding.status_extended = "x" * 2000 # it has to be limited to 1000+... + + expected = Check_Output_JSON_ASFF() + expected.Id = f"prowler-{finding.check_metadata.CheckID}-123456789012-eu-west-1-{hash_sha512('test-resource')}" + expected.ProductArn = "arn:aws:securityhub:eu-west-1::product/prowler/prowler" + expected.ProductFields = ProductFields( + ProviderVersion=prowler_version, ProwlerResourceName="test-arn" + ) + expected.GeneratorId = "prowler-" + finding.check_metadata.CheckID + expected.AwsAccountId = AWS_ACCOUNT_ID + expected.Types = finding.check_metadata.CheckType + expected.FirstObservedAt = ( + expected.UpdatedAt + ) = expected.CreatedAt = timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ") + expected.Severity = Severity(Label=finding.check_metadata.Severity.upper()) + expected.Title = finding.check_metadata.CheckTitle + expected.Description = finding.status_extended[:1000] + "..." + expected.Resources = [ + Resource( + Id="test-arn", + Type=finding.check_metadata.ResourceType, + Partition="aws", + Region="eu-west-1", + ) + ] + + expected.Compliance = Compliance( + Status="PASS" + "ED", + RelatedRequirements=[], + AssociatedStandards=[], + ) + + # Set the check's remediation + expected.Remediation = { + "Recommendation": finding.check_metadata.Remediation.Recommendation, + # "Code": finding.check_metadata.Remediation.Code, + } + + expected.Remediation[ + "Recommendation" + ].Text = finding.check_metadata.Remediation.Recommendation.Text + expected.Remediation[ + "Recommendation" + ].Url = "https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html" + + input = Check_Output_JSON_ASFF() + output_options = mock.MagicMock() + + assert ( + fill_json_asff(input, input_audit_info, finding, output_options) == expected + ) + + def test_fill_json_asff_with_long_associated_standards(self): + input_audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=None, + audited_account=AWS_ACCOUNT_ID, + audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_ID}:root", + audited_identity_arn="test-arn", + audited_user_id="test", + audited_partition="aws", + profile="default", + profile_region="eu-west-1", + credentials=None, + assumed_role_info=None, + audited_regions=["eu-west-2", "eu-west-1"], + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + ) + with patch( + "prowler.lib.outputs.json.get_check_compliance", + return_value={ + "CISA": ["your-systems-3", "your-data-2"], + "SOC2": ["cc_2_1", "cc_7_2", "cc_a_1_2"], + "CIS-1.4": ["3.1"], + "CIS-1.5": ["3.1"], + "GDPR": ["article_25", "article_30"], + "AWS-Foundational-Security-Best-Practices": ["cloudtrail"], + "HIPAA": [ + "164_308_a_1_ii_d", + "164_308_a_3_ii_a", + "164_308_a_6_ii", + "164_312_b", + "164_312_e_2_i", + ], + "ISO27001": ["A.12.4"], + "GxP-21-CFR-Part-11": ["11.10-e", "11.10-k", "11.300-d"], + "AWS-Well-Architected-Framework-Security-Pillar": [ + "SEC04-BP02", + "SEC04-BP03", + ], + "GxP-EU-Annex-11": [ + "1-risk-management", + "4.2-validation-documentation-change-control", + ], + "NIST-800-171-Revision-2": [ + "3_1_12", + "3_3_1", + "3_3_2", + "3_3_3", + "3_4_1", + "3_6_1", + "3_6_2", + "3_13_1", + "3_13_2", + "3_14_6", + "3_14_7", + ], + "NIST-800-53-Revision-4": [ + "ac_2_4", + "ac_2", + "au_2", + "au_3", + "au_12", + "cm_2", + ], + "NIST-800-53-Revision-5": [ + "ac_2_4", + "ac_3_1", + "ac_3_10", + "ac_4_26", + "ac_6_9", + "au_2_b", + "au_3_1", + "au_3_a", + "au_3_b", + "au_3_c", + "au_3_d", + "au_3_e", + "au_3_f", + "au_6_3", + "au_6_4", + "au_6_6", + "au_6_9", + "au_8_b", + "au_10", + "au_12_a", + "au_12_c", + "au_12_1", + "au_12_2", + "au_12_3", + "au_12_4", + "au_14_a", + "au_14_b", + "au_14_3", + "ca_7_b", + "cm_5_1_b", + "cm_6_a", + "cm_9_b", + "ia_3_3_b", + "ma_4_1_a", + "pm_14_a_1", + "pm_14_b", + "pm_31", + "sc_7_9_b", + "si_1_1_c", + "si_3_8_b", + "si_4_2", + "si_4_17", + "si_4_20", + "si_7_8", + "si_10_1_c", + ], + "ENS-RD2022": [ + "op.acc.6.r5.aws.iam.1", + "op.exp.5.aws.ct.1", + "op.exp.8.aws.ct.1", + "op.exp.8.aws.ct.6", + "op.exp.9.aws.ct.1", + "op.mon.1.aws.ct.1", + ], + "NIST-CSF-1.1": [ + "ae_1", + "ae_3", + "ae_4", + "cm_1", + "cm_3", + "cm_6", + "cm_7", + "am_3", + "ac_6", + "ds_5", + "ma_2", + "pt_1", + ], + "RBI-Cyber-Security-Framework": ["annex_i_7_4"], + "FFIEC": [ + "d2-ma-ma-b-1", + "d2-ma-ma-b-2", + "d3-dc-an-b-3", + "d3-dc-an-b-4", + "d3-dc-an-b-5", + "d3-dc-ev-b-1", + "d3-dc-ev-b-3", + "d3-pc-im-b-3", + "d3-pc-im-b-7", + "d5-dr-de-b-3", + ], + "PCI-3.2.1": ["cloudtrail"], + "FedRamp-Moderate-Revision-4": [ + "ac-2-4", + "ac-2-g", + "au-2-a-d", + "au-3", + "au-6-1-3", + "au-12-a-c", + "ca-7-a-b", + "si-4-16", + "si-4-2", + "si-4-4", + "si-4-5", + ], + "FedRAMP-Low-Revision-4": ["ac-2", "au-2", "ca-7"], + }, + ): + finding = Check_Report( + load_check_metadata( + f"{path.dirname(path.realpath(__file__))}/fixtures/metadata.json" + ).json() + ) + + # Empty the Remediation.Recomendation.URL + finding.check_metadata.Remediation.Recommendation.Url = "" + + finding.resource_details = "Test resource details" + finding.resource_id = "test-resource" + finding.resource_arn = "test-arn" + finding.region = "eu-west-1" + finding.status = "PASS" + finding.status_extended = "This is a test" + + expected = Check_Output_JSON_ASFF() + expected.Id = f"prowler-{finding.check_metadata.CheckID}-123456789012-eu-west-1-{hash_sha512('test-resource')}" + expected.ProductArn = ( + "arn:aws:securityhub:eu-west-1::product/prowler/prowler" + ) + expected.ProductFields = ProductFields( + ProviderVersion=prowler_version, ProwlerResourceName="test-arn" + ) + expected.GeneratorId = "prowler-" + finding.check_metadata.CheckID + expected.AwsAccountId = AWS_ACCOUNT_ID + expected.Types = finding.check_metadata.CheckType + expected.FirstObservedAt = ( + expected.UpdatedAt + ) = expected.CreatedAt = timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ") + expected.Severity = Severity(Label=finding.check_metadata.Severity.upper()) + expected.Title = finding.check_metadata.CheckTitle + expected.Description = finding.status_extended + expected.Resources = [ + Resource( + Id="test-arn", + Type=finding.check_metadata.ResourceType, + Partition="aws", + Region="eu-west-1", + ) + ] + + expected.Compliance = Compliance( + Status="PASS" + "ED", + RelatedRequirements=[ + "CISA your-systems-3 your-data-2", + "SOC2 cc_2_1 cc_7_2 cc_a_1_2", + "CIS-1.4 3.1", + "CIS-1.5 3.1", + "GDPR article_25 article_30", + "AWS-Foundational-Security-Best-Practices cloudtrail", + "HIPAA 164_308_a_1_ii_d 164_308_a_3_ii_a 164_308_a_6_ii 164_312_", + "ISO27001 A.12.4", + "GxP-21-CFR-Part-11 11.10-e 11.10-k 11.300-d", + "AWS-Well-Architected-Framework-Security-Pillar SEC04-BP02 SEC04", + "GxP-EU-Annex-11 1-risk-management 4.2-validation-documentation-", + "NIST-800-171-Revision-2 3_1_12 3_3_1 3_3_2 3_3_3 3_4_1 3_6_1 3_", + "NIST-800-53-Revision-4 ac_2_4 ac_2 au_2 au_3 au_12 cm_2", + "NIST-800-53-Revision-5 ac_2_4 ac_3_1 ac_3_10 ac_4_26 ac_6_9 au_", + "ENS-RD2022 op.acc.6.r5.aws.iam.1 op.exp.5.aws.ct.1 op.exp.8.aws", + "NIST-CSF-1.1 ae_1 ae_3 ae_4 cm_1 cm_3 cm_6 cm_7 am_3 ac_6 ds_5 ", + "RBI-Cyber-Security-Framework annex_i_7_4", + "FFIEC d2-ma-ma-b-1 d2-ma-ma-b-2 d3-dc-an-b-3 d3-dc-an-b-4 d3-dc", + "PCI-3.2.1 cloudtrail", + "FedRamp-Moderate-Revision-4 ac-2-4 ac-2-g au-2-a-d au-3 au-6-1-", + ], + AssociatedStandards=[ + {"StandardsId": "CISA"}, + {"StandardsId": "SOC2"}, + {"StandardsId": "CIS-1.4"}, + {"StandardsId": "CIS-1.5"}, + {"StandardsId": "GDPR"}, + {"StandardsId": "AWS-Foundational-Security-Best-Practices"}, + {"StandardsId": "HIPAA"}, + {"StandardsId": "ISO27001"}, + {"StandardsId": "GxP-21-CFR-Part-11"}, + {"StandardsId": "AWS-Well-Architected-Framework-Security-Pillar"}, + {"StandardsId": "GxP-EU-Annex-11"}, + {"StandardsId": "NIST-800-171-Revision-2"}, + {"StandardsId": "NIST-800-53-Revision-4"}, + {"StandardsId": "NIST-800-53-Revision-5"}, + {"StandardsId": "ENS-RD2022"}, + {"StandardsId": "NIST-CSF-1.1"}, + {"StandardsId": "RBI-Cyber-Security-Framework"}, + {"StandardsId": "FFIEC"}, + {"StandardsId": "PCI-3.2.1"}, + {"StandardsId": "FedRamp-Moderate-Revision-4"}, + ], + ) + + # Set the check's remediation + expected.Remediation = { + "Recommendation": finding.check_metadata.Remediation.Recommendation, + # "Code": finding.check_metadata.Remediation.Code, + } + + expected.Remediation[ + "Recommendation" + ].Text = finding.check_metadata.Remediation.Recommendation.Text + expected.Remediation[ + "Recommendation" + ].Url = "https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html" + + input = Check_Output_JSON_ASFF() + output_options = mock.MagicMock() + + assert ( + fill_json_asff(input, input_audit_info, finding, output_options) + == expected + ) + def test_fill_json_ocsf(self): input_audit_info = AWS_Audit_Info( session_config=None,