From 851286d23e725439ec0b8a0b66c9df6906755a2b Mon Sep 17 00:00:00 2001 From: "Andoni A." <14891798+andoniaf@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:25:55 +0200 Subject: [PATCH] fix(cloudwatch): if no CloudWatch log groups found resource arn should be the account --- ...h_changes_to_network_acls_alarm_configured.metadata.json | 4 ++-- .../cloudwatch_changes_to_network_acls_alarm_configured.py | 4 +++- ...anges_to_network_gateways_alarm_configured.metadata.json | 4 ++-- ...oudwatch_changes_to_network_gateways_alarm_configured.py | 4 +++- ...s_to_network_route_tables_alarm_configured.metadata.json | 4 ++-- ...atch_changes_to_network_route_tables_alarm_configured.py | 4 +++- ...loudwatch_changes_to_vpcs_alarm_configured.metadata.json | 4 ++-- .../cloudwatch_changes_to_vpcs_alarm_configured.py | 4 +++- .../providers/aws/services/cloudwatch/cloudwatch_service.py | 3 +++ ...udwatch_changes_to_network_acls_alarm_configured_test.py | 6 +++--- ...tch_changes_to_network_gateways_alarm_configured_test.py | 6 +++--- ...changes_to_network_route_tables_alarm_configured_test.py | 6 +++--- .../cloudwatch_changes_to_vpcs_alarm_configured_test.py | 6 +++--- 13 files changed, 35 insertions(+), 24 deletions(-) diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json index e6d496ed5f..3138f577cb 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json @@ -7,9 +7,9 @@ ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:account", "Severity": "medium", - "ResourceType": "AwsCloudWatchAlarm", + "ResourceType": "AwsAccount", "Description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL).", "Risk": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.", "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py index 20d68a0121..4ff4fd3118 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py @@ -31,7 +31,9 @@ class cloudwatch_changes_to_network_acls_alarm_configured(Check): report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." report.region = logs_client.region report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template + report.resource_arn = logs_client._get_account_arn_template( + logs_client.region + ) report.resource_tags = [] findings.append(report) diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json index 8dc004e5a7..3cb2721855 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json @@ -7,9 +7,9 @@ ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:account", "Severity": "medium", - "ResourceType": "AwsCloudWatchAlarm", + "ResourceType": "AwsAccount", "Description": "Ensure a log metric filter and alarm exist for changes to network gateways.", "Risk": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.", "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py index 5f6eda3973..399b325d13 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py @@ -31,7 +31,9 @@ class cloudwatch_changes_to_network_gateways_alarm_configured(Check): report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." report.region = logs_client.region report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template + report.resource_arn = logs_client._get_account_arn_template( + logs_client.region + ) report.resource_tags = [] findings.append(report) diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json index b25463c36b..29ba02276f 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json @@ -7,9 +7,9 @@ ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:account", "Severity": "medium", - "ResourceType": "AwsCloudWatchAlarm", + "ResourceType": "AwsAccount", "Description": "Real-time monitoring of API calls can be achieved by directing Cloud Trail Logs to CloudWatch Logs, or an external Security information and event management (SIEM)environment, and establishing corresponding metric filters and alarms. Routing tablesare used to route network traffic between subnets and to network gateways. It isrecommended that a metric filter and alarm be established for changes to route tables.", "Risk": "CloudWatch is an AWS native service that allows you to ob serve and monitor resources and applications. CloudTrail Logs can also be sent to an external Security informationand event management (SIEM) environment for monitoring and alerting.Monitoring changes to route tables will help ensure that all VPC traffic flows through anexpected path and prevent any accidental or intentional modifications that may lead touncontrolled network traffic. An alarm should be triggered every time an AWS API call isperformed to create, replace, delete, or disassociate a Route Table.", "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py index f8fcc8eacb..7d4dbbc3e0 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py @@ -31,7 +31,9 @@ class cloudwatch_changes_to_network_route_tables_alarm_configured(Check): report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." report.region = logs_client.region report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template + report.resource_arn = logs_client._get_account_arn_template( + logs_client.region + ) report.resource_tags = [] findings.append(report) diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json index 35ff876e1e..0c4fd81a2a 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json @@ -7,9 +7,9 @@ ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:account", "Severity": "medium", - "ResourceType": "AwsCloudWatchAlarm", + "ResourceType": "AwsAccount", "Description": "Ensure a log metric filter and alarm exist for VPC changes.", "Risk": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.", "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py index d7606647c4..6dbca2edb6 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py @@ -31,7 +31,9 @@ class cloudwatch_changes_to_vpcs_alarm_configured(Check): report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." report.region = logs_client.region report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template + report.resource_arn = logs_client._get_account_arn_template( + logs_client.region + ) report.resource_tags = [] findings.append(report) diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py index ac05ebae10..ebdcfb0dbb 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py @@ -102,6 +102,9 @@ class Logs(AWSService): self._list_tags_for_resource, self.log_groups.values() ) + def _get_account_arn_template(self, region): + return f"arn:{self.audited_partition}:cloudwatch:{region}:{self.audited_account}:account" + def _describe_metric_filters(self, regional_client): logger.info("CloudWatch Logs - Describing metric filters...") try: diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py index 66c2099843..704a01c26f 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py @@ -71,7 +71,7 @@ class Test_cloudwatch_changes_to_network_acls_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -139,7 +139,7 @@ class Test_cloudwatch_changes_to_network_acls_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_US_EAST_1 @@ -213,7 +213,7 @@ class Test_cloudwatch_changes_to_network_acls_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_US_EAST_1 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured_test.py index afe0f7d3ce..2ac31cde25 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured_test.py @@ -71,7 +71,7 @@ class Test_cloudwatch_changes_to_network_gateways_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -139,7 +139,7 @@ class Test_cloudwatch_changes_to_network_gateways_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -213,7 +213,7 @@ class Test_cloudwatch_changes_to_network_gateways_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured_test.py index 7ec6e32c56..17edbf852c 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured_test.py @@ -71,7 +71,7 @@ class Test_cloudwatch_changes_to_network_route_tables_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -139,7 +139,7 @@ class Test_cloudwatch_changes_to_network_route_tables_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -213,7 +213,7 @@ class Test_cloudwatch_changes_to_network_route_tables_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured_test.py index 31f27030ff..00e5c3932c 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured_test.py @@ -71,7 +71,7 @@ class Test_cloudwatch_changes_to_vpcs_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -139,7 +139,7 @@ class Test_cloudwatch_changes_to_vpcs_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1 @@ -213,7 +213,7 @@ class Test_cloudwatch_changes_to_vpcs_alarm_configured: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn - == f"arn:aws:logs:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:log-group" + == f"arn:aws:cloudwatch:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account" ) assert result[0].region == AWS_REGION_EU_WEST_1