From 3955450245376b6bcbac668f38071308a2062d47 Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Thu, 5 Oct 2023 15:49:43 +0200 Subject: [PATCH] fix(securityhub): archive SecurityHub findings in empty regions (#2908) --- .../aws/lib/security_hub/security_hub.py | 18 +++---- .../aws/lib/security_hub/security_hub_test.py | 48 ++++++++----------- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/prowler/providers/aws/lib/security_hub/security_hub.py b/prowler/providers/aws/lib/security_hub/security_hub.py index a5d3ede7..4b155312 100644 --- a/prowler/providers/aws/lib/security_hub/security_hub.py +++ b/prowler/providers/aws/lib/security_hub/security_hub.py @@ -11,9 +11,12 @@ SECURITY_HUB_MAX_BATCH = 100 def prepare_security_hub_findings( - findings: [], audit_info, output_options, enabled_regions: [] + findings: [], audit_info: AWS_Audit_Info, output_options, enabled_regions: [] ) -> dict: security_hub_findings_per_region = {} + # Create a key per region + for region in audit_info.audited_regions: + security_hub_findings_per_region[region] = [] for finding in findings: # We don't send the INFO findings to AWS Security Hub if finding.status == "INFO": @@ -30,10 +33,6 @@ def prepare_security_hub_findings( # Get the finding region region = finding.region - # Check if the security_hub_findings_per_region has the region, if not we have to create it - if region not in security_hub_findings_per_region: - security_hub_findings_per_region[region] = [] - # Format the finding in the JSON ASFF format finding_json_asff = fill_json_asff( Check_Output_JSON_ASFF(), audit_info, finding, output_options @@ -117,9 +116,10 @@ def resolve_security_hub_previous_findings( resolve_security_hub_previous_findings archives all the findings that does not appear in the current execution """ logger.info("Checking previous findings in Security Hub to archive them.") - - for region, current_findings in security_hub_findings_per_region.items(): + success_count = 0 + for region in security_hub_findings_per_region.keys(): try: + current_findings = security_hub_findings_per_region[region] # Get current findings IDs current_findings_ids = [] for finding in current_findings: @@ -151,14 +151,14 @@ def resolve_security_hub_previous_findings( logger.info(f"Archiving {len(findings_to_archive)} findings.") # Send archive findings to SHub - success_count = __send_findings_to_security_hub__( + success_count += __send_findings_to_security_hub__( findings_to_archive, region, security_hub_client ) - return success_count except Exception as error: logger.error( f"{error.__class__.__name__} -- [{error.__traceback__.tb_lineno}]:{error} in region {region}" ) + return success_count def __send_findings_to_security_hub__( diff --git a/tests/providers/aws/lib/security_hub/security_hub_test.py b/tests/providers/aws/lib/security_hub/security_hub_test.py index d07774bc..241e163b 100644 --- a/tests/providers/aws/lib/security_hub/security_hub_test.py +++ b/tests/providers/aws/lib/security_hub/security_hub_test.py @@ -159,7 +159,8 @@ class Test_SecurityHub: } }, } - ] + ], + AWS_REGION_2: [], } def test_prepare_security_hub_findings_quiet_INFO_finding(self): @@ -168,15 +169,12 @@ class Test_SecurityHub: findings = [self.generate_finding("INFO", AWS_REGION_1)] audit_info = self.set_mocked_audit_info() - assert ( - prepare_security_hub_findings( - findings, - audit_info, - output_options, - enabled_regions, - ) - == {} - ) + assert prepare_security_hub_findings( + findings, + audit_info, + output_options, + enabled_regions, + ) == {AWS_REGION_1: [], AWS_REGION_2: []} def test_prepare_security_hub_findings_disabled_region(self): enabled_regions = [AWS_REGION_1] @@ -184,15 +182,12 @@ class Test_SecurityHub: findings = [self.generate_finding("PASS", AWS_REGION_2)] audit_info = self.set_mocked_audit_info() - assert ( - prepare_security_hub_findings( - findings, - audit_info, - output_options, - enabled_regions, - ) - == {} - ) + assert prepare_security_hub_findings( + findings, + audit_info, + output_options, + enabled_regions, + ) == {AWS_REGION_1: [], AWS_REGION_2: []} def test_prepare_security_hub_findings_quiet(self): enabled_regions = [AWS_REGION_1] @@ -200,15 +195,12 @@ class Test_SecurityHub: findings = [self.generate_finding("PASS", AWS_REGION_1)] audit_info = self.set_mocked_audit_info() - assert ( - prepare_security_hub_findings( - findings, - audit_info, - output_options, - enabled_regions, - ) - == {} - ) + assert prepare_security_hub_findings( + findings, + audit_info, + output_options, + enabled_regions, + ) == {AWS_REGION_1: [], AWS_REGION_2: []} @patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) def test_batch_send_to_security_hub_one_finding(self):