From 23e3ea4a41d9cddb6e58bf81c7f3ba9ad384def1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20De=20la=20Torre=20Vico?= Date: Thu, 30 Oct 2025 14:08:18 +0100 Subject: [PATCH] chore(aws): enhance metadata for `cloudwatch` service (#8848) Co-authored-by: HugoPBrito Co-authored-by: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com> --- prowler/CHANGELOG.md | 1 + ...tions_alarm_state_configured.metadata.json | 35 ++++++++++------ ...dwatch_alarm_actions_enabled.metadata.json | 33 +++++++++------ ...etwork_acls_alarm_configured.metadata.json | 35 ++++++++++------ ...rk_gateways_alarm_configured.metadata.json | 36 +++++++++++------ ...oute_tables_alarm_configured.metadata.json | 33 +++++++++------ ...ges_to_vpcs_alarm_configured.metadata.json | 28 ++++++++----- ...oss_account_sharing_disabled.metadata.json | 32 +++++++++------ ...group_kms_encryption_enabled.metadata.json | 35 ++++++++++------ ...log_group_no_secrets_in_logs.metadata.json | 39 ++++++++++-------- ...roup_not_publicly_accessible.metadata.json | 30 ++++++++------ ...policy_specific_days_enabled.metadata.json | 40 +++++++++++++------ ...onfiguration_changes_enabled.metadata.json | 32 +++++++++------ ...onfiguration_changes_enabled.metadata.json | 34 ++++++++++------ ...lter_authentication_failures.metadata.json | 37 +++++++++++------ ...er_aws_organizations_changes.metadata.json | 35 ++++++++++------ ...cheduled_deletion_of_kms_cmk.metadata.json | 29 ++++++++------ ...for_s3_bucket_policy_changes.metadata.json | 33 +++++++++------ ...metric_filter_policy_changes.metadata.json | 33 +++++++++------ ...log_metric_filter_root_usage.metadata.json | 39 ++++++++++++------ ...ilter_security_group_changes.metadata.json | 34 ++++++++++------ ...c_filter_sign_in_without_mfa.metadata.json | 38 ++++++++++++------ ...ilter_unauthorized_api_calls.metadata.json | 37 +++++++++++------ 23 files changed, 488 insertions(+), 270 deletions(-) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 830d0f5ec9..c9b6341263 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Update AWS DRS service metadata to new format [(#8870)](https://github.com/prowler-cloud/prowler/pull/8870) - C5 compliance framework for Azure provider [(#9081)](https://github.com/prowler-cloud/prowler/pull/9081) - Update AWS DynamoDB service metadata to new format [(#8871)](https://github.com/prowler-cloud/prowler/pull/8871) +- Update AWS CloudWatch service metadata to new format [(#8848)](https://github.com/prowler-cloud/prowler/pull/8848) - Update AWS EMR service metadata to new format [(#9002)](https://github.com/prowler-cloud/prowler/pull/9002) - Update AWS EKS service metadata to new format [(#8890)](https://github.com/prowler-cloud/prowler/pull/8890) - Update AWS ElastiCache service metadata to new format [(#8933)](https://github.com/prowler-cloud/prowler/pull/8933) diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_alarm_state_configured/cloudwatch_alarm_actions_alarm_state_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_alarm_state_configured/cloudwatch_alarm_actions_alarm_state_configured.metadata.json index 15d14cbb5d..2ba6edd624 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_alarm_state_configured/cloudwatch_alarm_actions_alarm_state_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_alarm_state_configured/cloudwatch_alarm_actions_alarm_state_configured.metadata.json @@ -1,31 +1,42 @@ { "Provider": "aws", "CheckID": "cloudwatch_alarm_actions_alarm_state_configured", - "CheckTitle": "Check if CloudWatch alarms have specified actions configured for the ALARM state.", + "CheckTitle": "CloudWatch metric alarm has actions configured for the ALARM state", "CheckType": [ "Software and Configuration Checks/AWS Security Best Practices" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:cloudwatch:region:account-id:alarm/alarm-name", + "ResourceIdTemplate": "", "Severity": "high", "ResourceType": "AwsCloudWatchAlarm", - "Description": "This control checks whether an Amazon CloudWatch alarm has at least one action configured for the ALARM state. The control fails if the alarm doesn't have an action configured for the ALARM state.", - "Risk": "Without an action configured for the ALARM state, the CloudWatch alarm will not notify you or take any predefined action when a monitored metric goes beyond the defined threshold, potentially delaying responses to critical events.", - "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-actions", + "Description": "Amazon CloudWatch metric alarms are evaluated for **actions** configured for the `ALARM` state. The finding flags alarms that have no action to execute when their monitored metric crosses its threshold.", + "Risk": "Without an **ALARM action**, threshold breaches trigger no **notification** or **automated response**. This delays detection and containment, risking:\n- Availability: prolonged outages or missed scale-out\n- Integrity/confidentiality: unchecked anomalies enabling tampering or data loss", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-actions", + "https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudwatch/client/put_metric_alarm.html", + "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm", + "https://docs.aws.amazon.com/securityhub/latest/userguide/cloudwatch-controls.html#cloudwatch-15", + "https://support.icompaas.com/support/solutions/articles/62000233431-ensure-cloudwatch-alarms-have-specified-actions-configured-for-the-alarm-state", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatch/cloudwatch-alarm-action.html", + "https://awscli.amazonaws.com/v2/documentation/api/2.0.34/reference/cloudwatch/put-metric-alarm.html" + ], "Remediation": { "Code": { - "CLI": "aws cloudwatch put-metric-alarm --alarm-name --alarm-actions ", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/cloudwatch-controls.html#cloudwatch-15", - "Terraform": "" + "CLI": "aws cloudwatch put-metric-alarm --alarm-name --metric-name --namespace --statistic --period --evaluation-periods --threshold --comparison-operator --alarm-actions ", + "NativeIaC": "```yaml\n# CloudFormation: add an ALARM action to a metric alarm\nResources:\n :\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: \n MetricName: \n Namespace: \n Statistic: Average\n Period: 60\n EvaluationPeriods: 1\n Threshold: 1\n ComparisonOperator: GreaterThanThreshold\n AlarmActions:\n - # CRITICAL: adds an action for ALARM state so the check passes\n```", + "Other": "1. Open the AWS Console and go to CloudWatch > Alarms\n2. Select the target alarm and choose Edit (or Modify alarm)\n3. In Actions, under When alarm state is ALARM, add an action (e.g., select an SNS topic or other supported action)\n4. Click Save changes", + "Terraform": "```hcl\n# Terraform: add an ALARM action to a metric alarm\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n alarm_name = \"\"\n metric_name = \"\"\n namespace = \"\"\n statistic = \"Average\"\n period = 60\n evaluation_periods = 1\n threshold = 1\n comparison_operator = \"GreaterThanThreshold\"\n alarm_actions = [\"\"] # CRITICAL: ensures an action is configured for ALARM state\n}\n```" }, "Recommendation": { - "Text": "Configure your CloudWatch alarms to trigger actions, such as sending notifications via Amazon SNS, when the alarm state changes to ALARM.", - "Url": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatch/cloudwatch-alarm-action.html" + "Text": "Assign at least one **ALARM-state action** per alarm (e.g., notify via SNS or run automated remediation with Lambda/SSM). Keep actions enabled, apply **least privilege** to targets, and regularly test. *For critical metrics*, add redundant paths (EventBridge) for **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudwatch_alarm_actions_alarm_state_configured" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_enabled/cloudwatch_alarm_actions_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_enabled/cloudwatch_alarm_actions_enabled.metadata.json index 7f2b24c09e..6e87dddbce 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_enabled/cloudwatch_alarm_actions_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_enabled/cloudwatch_alarm_actions_enabled.metadata.json @@ -1,31 +1,40 @@ { "Provider": "aws", "CheckID": "cloudwatch_alarm_actions_enabled", - "CheckTitle": "Check if CloudWatch alarms have actions enabled", + "CheckTitle": "CloudWatch metric alarm has actions enabled", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices", + "Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "TTPs/Defense Evasion" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:cloudwatch:region:account-id:alarm/alarm-name", + "ResourceIdTemplate": "", "Severity": "high", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Alarm actions automatically alert you when a monitored metric is outside the defined threshold. If the alarm action is deactivated, no actions are run when the alarm changes state, and you won't be alerted to changes in monitored metrics. We recommend activating CloudWatch alarm actions to help you quickly respond to security and operational issues.", - "Risk": "Without active alarm actions, you may not be alerted to security or operational issues, potentially leading to delayed responses and increased risk.", - "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-actions", + "Description": "**CloudWatch metric alarms** are evaluated for **alarm actions** activation (`actions_enabled: true`), enabling state changes to invoke configured notifications or automated responses.", + "Risk": "With alarm actions disabled, state changes neither notify nor remediate. Incidents can persist unnoticed, enabling unauthorized activity, configuration drift, or capacity exhaustion. Visibility drops, MTTR rises, and confidentiality, integrity, and availability are all at greater risk.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatch/cloudwatch-alarm-action-activated.html", + "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-actions", + "https://docs.aws.amazon.com/securityhub/latest/userguide/cloudwatch-controls.html#cloudwatch-17" + ], "Remediation": { "Code": { "CLI": "aws cloudwatch enable-alarm-actions --alarm-names ", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/cloudwatch-controls.html#cloudwatch-17", - "Terraform": "" + "NativeIaC": "```yaml\nResources:\n :\n Type: AWS::CloudWatch::Alarm\n Properties:\n ActionsEnabled: true # FIX: activates alarm actions so the check passes\n ComparisonOperator: GreaterThanThreshold\n EvaluationPeriods: 1\n MetricName: \n Namespace: \n Period: 60\n Statistic: Average\n Threshold: 1\n```", + "Other": "1. Open the CloudWatch console\n2. Go to Alarms > All alarms and select the alarm\n3. Choose Actions > Alarm actions - new > Enable\n4. Confirm to activate actions", + "Terraform": "```hcl\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n alarm_name = \"\"\n comparison_operator = \"GreaterThanThreshold\"\n evaluation_periods = 1\n metric_name = \"\"\n namespace = \"\"\n period = 60\n statistic = \"Average\"\n threshold = 1\n\n actions_enabled = true # FIX: activates alarm actions so the check passes\n}\n```" }, "Recommendation": { - "Text": "Ensure that all CloudWatch alarms have at least one action configured. This can include sending notifications to SNS topics, invoking Lambda functions, or triggering other AWS services.", - "Url": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatch/cloudwatch-alarm-action-activated.html" + "Text": "Enable `actions_enabled` on critical alarms and attach least-privilege actions (SNS, automation) for ALARM and recovery states. Use redundant targets, regularly test notifications, and integrate with incident response. Apply **defense in depth** with complementary detections to ensure timely, reliable alerting.", + "Url": "https://hub.prowler.com/check/cloudwatch_alarm_actions_enabled" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" 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..5ff31680d4 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 @@ -1,31 +1,42 @@ { "Provider": "aws", "CheckID": "cloudwatch_changes_to_network_acls_alarm_configured", - "CheckTitle": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL).", + "CheckTitle": "CloudWatch log metric filter and alarm exist for Network ACL (NACL) change events", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "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", + "Description": "CloudTrail records for **Network ACL changes** are matched by a CloudWatch Logs metric filter with an associated alarm for events like `CreateNetworkAcl`, `CreateNetworkAclEntry`, `DeleteNetworkAcl`, `DeleteNetworkAclEntry`, `ReplaceNetworkAclEntry`, and `ReplaceNetworkAclAssociation`.", + "Risk": "Absent monitoring of **NACL changes** reduces detection of policy tampering, risking loss of **confidentiality** (opened ingress/egress), degraded network **integrity** (lateral movement, bypassed segmentation), and reduced **availability** (traffic blackholes or lockouts).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://www.clouddefense.ai/compliance-rules/cis-v130/monitoring/cis-v130-4-11", + "https://support.icompaas.com/support/solutions/articles/62000084031-ensure-a-log-metric-filter-and-alarm-exist-for-changes-to-network-access-control-lists-nacl-", + "https://trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/network-acl-changes-alarm.html", + "https://support.icompaas.com/support/solutions/articles/62000233134-4-11-ensure-network-access-control-list-nacl-changes-are-monitored-manual-" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_11", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_11#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation to alert on NACL changes\nResources:\n MetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \"\" # CRITICAL: CloudTrail log group to monitor\n FilterPattern: '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' # CRITICAL: detects NACL changes\n MetricTransformations:\n - MetricValue: \"1\"\n MetricNamespace: \"CISBenchmark\"\n MetricName: \"nacl_changes\"\n\n NaclChangesAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: \"nacl_changes\"\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n MetricName: \"nacl_changes\" # CRITICAL: alarm targets the metric from the filter\n Namespace: \"CISBenchmark\"\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS Console, go to CloudWatch > Log groups and open the CloudTrail log group\n2. Metric filters tab > Create metric filter\n3. Set Filter pattern to:\n { ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\n4. Next > Filter name: nacl_changes; Metric namespace: CISBenchmark; Metric name: nacl_changes; Metric value: 1 > Create metric filter\n5. Select the new metric filter > Create alarm\n6. Set Statistic: Sum, Period: 5 minutes, Threshold type: Static, Condition: Greater/Equal, Threshold: 1\n7. Next through actions (optional) > Name: nacl_changes > Create alarm", + "Terraform": "```hcl\n# CloudWatch metric filter and alarm for NACL changes\nresource \"aws_cloudwatch_log_metric_filter\" \"nacl\" {\n name = \"nacl_changes\"\n log_group_name = \"\" # CloudTrail log group\n pattern = \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" # CRITICAL: detects NACL changes\n\n metric_transformation {\n name = \"nacl_changes\"\n namespace = \"CISBenchmark\"\n value = \"1\"\n }\n}\n\nresource \"aws_cloudwatch_metric_alarm\" \"nacl\" {\n alarm_name = \"nacl_changes\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n metric_name = \"nacl_changes\" # CRITICAL: alarm targets the metric from the filter\n namespace = \"CISBenchmark\"\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Implement a CloudWatch Logs metric filter and alarm for NACL change events from CloudTrail and route alerts to responders. Enforce **least privilege** on NACL management, require **change control**, and use **defense in depth** with configuration monitoring and flow logs to validate and monitor network posture.", + "Url": "https://hub.prowler.com/check/cloudwatch_changes_to_network_acls_alarm_configured" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" 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..5929489df9 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 @@ -1,31 +1,43 @@ { "Provider": "aws", "CheckID": "cloudwatch_changes_to_network_gateways_alarm_configured", - "CheckTitle": "Ensure a log metric filter and alarm exist for changes to network gateways.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for changes to network gateways", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability", + "TTPs/Command and Control" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "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", + "Description": "CloudWatch log metric filters and alarms for **network gateway changes** are identified by matching CloudTrail events such as `CreateCustomerGateway`, `DeleteCustomerGateway`, `AttachInternetGateway`, `CreateInternetGateway`, `DeleteInternetGateway`, and `DetachInternetGateway` in log groups that receive trail logs.", + "Risk": "Without this monitoring, gateway changes can expose private networks to the Internet or break connectivity. Adversaries or mistakes can enable data exfiltration, bypass network inspection, and trigger outages via deletions or detachments, impacting **confidentiality** and **availability**.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://support.icompaas.com/support/solutions/articles/62000083807-ensure-a-log-metric-filter-and-alarm-exist-for-changes-to-network-gateways", + "https://docs.aws.amazon.com/securityhub/latest/userguide/cloudwatch-controls.html#cloudwatch-12", + "https://paper.bobylive.com/Security/CIS/CIS_Amazon_Web_Services_Foundations_Benchmark_v1_3_0.pdf" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_12", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_12#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for network gateway changes\nResources:\n NetworkGatewayMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n FilterPattern: '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' # Critical: matches gateway change events\n MetricTransformations:\n - MetricName: \n MetricNamespace: \n MetricValue: \"1\"\n\n NetworkGatewayAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n MetricName: # Critical: alarm targets the metric created by the filter\n Namespace: \n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS Console, go to CloudWatch > Logs > Log groups and open the CloudTrail log group\n2. Create metric filter:\n - Filter pattern: { ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\n - Metric name: \n - Metric namespace: \n - Metric value: 1\n3. From the filter, choose Create alarm:\n - Statistic: Sum, Period: 5 minutes, Threshold: >= 1, Evaluation periods: 1\n - Create the alarm (actions optional)\n", + "Terraform": "```hcl\n# CloudWatch Logs metric filter for network gateway changes\nresource \"aws_cloudwatch_log_metric_filter\" \"\" {\n name = \"\"\n log_group_name = \"\"\n pattern = \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" # Critical: matches gateway change events\n\n metric_transformation {\n name = \"\"\n namespace = \"\"\n value = \"1\"\n }\n}\n\n# Alarm on the metric filter\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n alarm_name = \"\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n metric_name = \"\" # Critical: must match metric from the filter\n namespace = \"\"\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Send CloudTrail to CloudWatch Logs and create a metric filter for the listed gateway events with an alarm that notifies responders. Enforce **least privilege** for gateway modifications, require change approvals, and route alerts to monitored channels as part of **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudwatch_changes_to_network_gateways_alarm_configured" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" 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..1a8b274bf3 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 @@ -1,31 +1,40 @@ { "Provider": "aws", "CheckID": "cloudwatch_changes_to_network_route_tables_alarm_configured", - "CheckTitle": "Ensure route table changes are monitored", + "CheckTitle": "Account monitors VPC route table changes with a CloudWatch Logs metric filter and alarm", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices", + "TTPs/Defense Evasion", + "Effects/Data Exfiltration" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "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", + "Description": "**VPC route table changes** are captured from **CloudTrail logs** by a **CloudWatch Logs metric filter** with an associated **alarm** for events like `CreateRoute`, `CreateRouteTable`, `ReplaceRoute`, `ReplaceRouteTableAssociation`, `DeleteRoute`, `DeleteRouteTable`, and `DisassociateRouteTable`.", + "Risk": "Without monitoring of **route table changes**, unauthorized or accidental edits can redirect traffic, bypass inspection, or blackhole routes, impacting **confidentiality** (exfiltration), **integrity** (tampered paths), and **availability** (outages from misrouted traffic).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_13", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_13#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Metric filter + alarm for VPC route table changes\nResources:\n RouteTableChangeMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \"\"\n # CRITICAL: Detect EC2 route table change events in CloudTrail logs\n # Includes eventSource and the required eventNames\n FilterPattern: '{($.eventSource = ec2.amazonaws.com) && (($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable))}'\n MetricTransformations:\n - MetricValue: \"1\"\n MetricNamespace: \"\"\n MetricName: \"\"\n\n RouteTableChangeAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n # CRITICAL: Alarm on the metric from the filter above\n Namespace: \"\"\n MetricName: \"\"\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS console, open CloudWatch > Log groups and select your CloudTrail log group\n2. Go to Metric filters > Create metric filter\n3. Set Filter pattern to:\n {($.eventSource = ec2.amazonaws.com) && (($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable))}\n4. Name the metric and set Metric value to 1; choose any namespace/name\n5. Create the filter\n6. From the filter, click Create alarm\n7. Set Statistic: Sum, Period: 5 minutes, Threshold type: Static, Threshold: 1, Whenever: Greater/Equal\n8. Create the alarm (notifications optional)", + "Terraform": "```hcl\n# Metric filter + alarm for VPC route table changes\nresource \"aws_cloudwatch_log_metric_filter\" \"routes\" {\n name = \"\"\n log_group_name = \"\"\n # CRITICAL: Detect EC2 route table change events in CloudTrail logs\n pattern = \"{($.eventSource = ec2.amazonaws.com) && (($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable))}\"\n\n metric_transformation {\n name = \"\"\n namespace = \"\"\n value = \"1\"\n }\n}\n\nresource \"aws_cloudwatch_metric_alarm\" \"routes\" {\n alarm_name = \"\"\n # CRITICAL: Alarm targets the metric from the filter above\n metric_name = \"\"\n namespace = \"\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "If you are using CloudTrails and CloudWatch, perform the following to setup the metric filter, alarm, SNS topic, and subscription: 1. Create a metric filter based on filter pattern provided which checks for route table changes and the taken from audit step 1. aws logs put-metric-filter --log-group-name -- filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = ec2.amazonaws.com) && (($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable)) }' Note: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together. 2. Create an SNS topic that the alarm will notify aws sns create-topic --name Note: you can execute this command once and then re-use the same topic for all monitoring alarms. 3. Create an SNS subscription to the topic created in step 2 aws sns subscribe --topic-arn --protocol - -notification-endpoint Note: you can execute this command once and then re-use the SNS subscription for all monitoring alarms. 4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 - -threshold 1 --comparison-operator GreaterThanOrEqualToThreshold -- evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions ", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Implement a **CloudWatch Logs metric filter and alarm** on CloudTrail for these route table events and notify responders. Enforce **least privilege** for route modifications, require **change control**, and apply **defense in depth** with VPC Flow Logs and guardrails to prevent and quickly contain unsafe routing changes.", + "Url": "https://hub.prowler.com/check/cloudwatch_changes_to_network_route_tables_alarm_configured" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" 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..a86873565b 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 @@ -1,31 +1,37 @@ { "Provider": "aws", "CheckID": "cloudwatch_changes_to_vpcs_alarm_configured", - "CheckTitle": "Ensure a log metric filter and alarm exist for VPC changes.", + "CheckTitle": "AWS account has a CloudWatch Logs metric filter and alarm for VPC changes", "CheckType": [ "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "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", + "Description": "**CloudTrail events** for **VPC configuration changes** are captured in CloudWatch Logs with a metric filter and an associated alarm. The filter targets actions like `CreateVpc`, `DeleteVpc`, `ModifyVpcAttribute`, and VPC peering operations to surface when network topology is altered.", + "Risk": "Without alerting on VPC changes, unauthorized or accidental edits to routes, peering, or attributes can go unnoticed, exposing private networks and enabling data exfiltration (C), lateral movement and traffic tampering (I), and outages from misrouted or bridged networks (A).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_14", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_14#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create a metric filter and alarm for VPC changes\nResources:\n VPCChangesMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n FilterPattern: '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' # Critical: matches VPC change events\n MetricTransformations:\n - MetricName: vpc_changes_metric\n MetricNamespace: CISBenchmark\n MetricValue: \"1\" # Critical: emits a metric on matching events\n\n VPCChangesAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n MetricName: vpc_changes_metric # Critical: alarm monitors the metric above\n Namespace: CISBenchmark\n Statistic: Sum\n Period: 300\n EvaluationPeriods: 1\n Threshold: 1\n ComparisonOperator: GreaterThanOrEqualToThreshold\n```", + "Other": "1. In the AWS Console, go to CloudWatch > Log groups and open the CloudTrail log group\n2. Choose Create metric filter\n3. For Filter pattern, paste:\n { ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\n4. Name the filter and set Metric namespace to CISBenchmark, Metric name to vpc_changes_metric, Metric value to 1; create the filter\n5. Select the new filter and choose Create alarm\n6. Set Statistic to Sum, Period 5 minutes, Threshold type Static, Whenever Greater/Equal 1, Evaluation periods 1\n7. Create the alarm (actions/notifications are optional and not required for pass)\n", + "Terraform": "```hcl\n# Metric filter for VPC changes\nresource \"aws_cloudwatch_log_metric_filter\" \"\" {\n name = \"\"\n log_group_name = \"\"\n pattern = \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" # Critical: matches VPC change events\n\n metric_transformation {\n name = \"\" # Critical: metric created by the filter\n namespace = \"CISBenchmark\"\n value = \"1\"\n }\n}\n\n# Alarm on the VPC changes metric\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n metric_name = \"\" # Critical: alarm monitors the filter's metric\n namespace = \"CISBenchmark\"\n statistic = \"Sum\"\n period = 300\n evaluation_periods = 1\n threshold = 1\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Create a CloudWatch Logs metric filter and alarm on CloudTrail for critical **VPC change events**, and notify responders. Apply **least privilege** to network changes, require change approvals, and use **defense in depth** (segmentation, route controls) to prevent and contain unauthorized modifications.", + "Url": "https://hub.prowler.com/check/cloudwatch_changes_to_vpcs_alarm_configured" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.metadata.json index a6a9e1839c..a799d923b2 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.metadata.json @@ -1,31 +1,39 @@ { "Provider": "aws", "CheckID": "cloudwatch_cross_account_sharing_disabled", - "CheckTitle": "Check if CloudWatch has allowed cross-account sharing.", + "CheckTitle": "CloudWatch does not allow cross-account sharing", "CheckType": [ - "Logging and Monitoring" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Effects/Data Exposure" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", - "ResourceType": "AwsAccount", - "Description": "Check if CloudWatch has allowed cross-account sharing.", - "Risk": "Cross-Account access to CloudWatch could increase the risk of compromising information between accounts.", - "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Cross-Account-Cross-Region.html", + "ResourceType": "AwsIamRole", + "Description": "**Amazon CloudWatch** cross-account sharing via the `CloudWatch-CrossAccountSharingRole` allows other AWS accounts to view your metrics, dashboards, and alarms. The presence of this role indicates that sharing is active.", + "Risk": "Granting other accounts visibility into observability data reduces **confidentiality** and enables **reconnaissance**. Adversaries or over-privileged partners can map architectures, profile workloads, and spot alerting gaps, increasing chances of **lateral movement** and **evasion**.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Cross-Account-Cross-Region.html" + ], "Remediation": { "Code": { - "CLI": "", + "CLI": "aws cloudformation delete-stack --stack-name CloudWatch-CrossAccountSharingRole", "NativeIaC": "", - "Other": "", + "Other": "1. Sign in to the AWS Management Console and open IAM\n2. Go to Roles\n3. Find and select the role named \"CloudWatch-CrossAccountSharingRole\"\n4. Click Delete and confirm\n5. If deletion is blocked because it is managed by CloudFormation: open CloudFormation, select the stack named \"CloudWatch-CrossAccountSharingRole\", and click Delete", "Terraform": "" }, "Recommendation": { - "Text": "Grant usage permission on a per-resource basis to enforce least privilege and Zero Trust principles.", - "Url": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Cross-Account-Cross-Region.html" + "Text": "Disable **cross-account sharing** unless strictly required. If needed, restrict access to specific trusted accounts, scope read-only permissions to only necessary resources, and use a dedicated monitoring account. Apply **least privilege** and **separation of duties**, and regularly audit role trust and access patterns.", + "Url": "https://hub.prowler.com/check/cloudwatch_cross_account_sharing_disabled" } }, - "Categories": [], + "Categories": [ + "trust-boundaries", + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json index c4a6601f6f..8344ee43ad 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json @@ -1,28 +1,37 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_group_kms_encryption_enabled", - "CheckTitle": "Check if CloudWatch log groups are protected by AWS KMS.", + "CheckTitle": "CloudWatch log group is encrypted with an AWS KMS key", "CheckType": [ - "Data Protection" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Effects/Data Exposure" ], "ServiceName": "cloudwatch", - "SubServiceName": "logs", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "SubServiceName": "", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Check if CloudWatch log groups are protected by AWS KMS.", - "Risk": "Using customer managed KMS to encrypt CloudWatch log group provide additional confidentiality and control over the log data.", - "RelatedUrl": "https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html", + "Description": "**CloudWatch log groups** are assessed for **at-rest encryption** by checking if an **AWS KMS key** is associated with the log group via `kmsKeyId`.", + "Risk": "Without a **customer-managed KMS key**, logs rely on service-managed encryption, limiting control and auditability.\n- Confidentiality: weaker key-policy barriers against unauthorized reads\n- Integrity/availability: no custom rotation or rapid revoke, hindering incident response and compliance", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html", + "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group", + "https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs/client/associate_kms_key.html", + "https://support.icompaas.com/support/solutions/articles/62000233436-ensure-cloudwatch-log-groups-are-protected-by-aws-kms", + "https://varunmanik1.medium.com/proactively-mitigating-a-medium-severity-prowler-issue-enabling-kms-encryption-for-cloudwatch-logs-51d43416c7fc" + ], "Remediation": { "Code": { - "CLI": "associate-kms-key --log-group-name --kms-key-id ", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_21#aws-console", - "Terraform": "" + "CLI": "aws logs associate-kms-key --log-group-name --kms-key-id arn:aws:kms:::key/", + "NativeIaC": "```yaml\n# CloudFormation: Encrypt a CloudWatch Log Group with KMS\nResources:\n :\n Type: AWS::Logs::LogGroup\n Properties:\n KmsKeyId: arn:aws:kms:::key/ # Critical: associates a CMK to encrypt the log group\n```", + "Other": "1. In the AWS Console, go to CloudWatch > Log groups\n2. Click Create log group and enter a name\n3. Under Encryption, select KMS key and provide the key ARN\n4. Click Create log group\n5. For existing log groups, the console cannot attach a KMS key; use the CLI command provided", + "Terraform": "```hcl\n# Encrypt a CloudWatch Log Group with KMS\nresource \"aws_cloudwatch_log_group\" \"\" {\n name = \"\"\n kms_key_id = \"arn:aws:kms:::key/\" # Critical: associates a CMK to encrypt the log group\n}\n```" }, "Recommendation": { - "Text": "Associate KMS Key with Cloudwatch log group.", - "Url": "https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html" + "Text": "Associate each log group with a **customer-managed KMS key** via `kmsKeyId`.\n- Enforce **least privilege** in key and IAM policies, granting `kms:Decrypt` only to required principals\n- Enable rotation and monitor key usage\n- Separate keys by app/tenant to support **defense in depth** and rapid revocation", + "Url": "https://hub.prowler.com/check/cloudwatch_log_group_kms_encryption_enabled" } }, "Categories": [ diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.metadata.json index 087b16a89f..c661c3157e 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.metadata.json @@ -1,38 +1,43 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_group_no_secrets_in_logs", - "CheckTitle": "Check if secrets exists in CloudWatch logs.", + "CheckTitle": "CloudWatch log group contains no secrets in its log events", "CheckType": [ - "Protect", - "Secure development" + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "Sensitive Data Identifications/Passwords", + "Sensitive Data Identifications/Security", + "Effects/Data Exposure" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:log-group/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Check if secrets exists in CloudWatch logs", - "Risk": "Storing sensitive data in CloudWatch logs could allow an attacker with read-only access to escalate their privileges or gain unauthorised access to systems.", - "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "Description": "**CloudWatch Logs** log groups are analyzed for potential **secrets** embedded in log events across their streams. Detection flags patterns resembling credentials (API keys, passwords, tokens, keys) and reports the secret types and where they appear within the log group.", + "Risk": "Leaked **credentials in logs** erode confidentiality and enable unauthorized API calls. Attackers reusing tokens/keys can escalate privileges, alter resources, and exfiltrate data. Subscriptions and exports widen exposure, and users with `logs:Unmask` can reveal values, increasing the blast radius.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://support.icompaas.com/support/solutions/articles/62000233413-ensure-secrets-are-not-logged-in-cloudwatch-logs", + "https://awsfundamentals.com/blog/masking-sensitive-data-with-amazon-cloudwatch-logs-data-protection-policies", + "https://repost.aws/questions/QUermjg18CSMqfSKo4CuTAaA/hide-sensitive-data-in-cloudwatch-logs", + "https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/mask-sensitive-log-data.html", + "https://levelup.gitconnected.com/masking-sensitive-data-in-aws-cloudwatch-logs-1b3c66d0ddcb" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "aws logs put-data-protection-policy --log-group-identifier --policy-document '{\"Statement\":[{\"DataIdentifier\":[\"arn:aws:dataprotection::aws:data-identifier/Credentials\"],\"Operation\":{\"Audit\":{\"FindingsDestination\":{}}}},{\"DataIdentifier\":[\"arn:aws:dataprotection::aws:data-identifier/Credentials\"],\"Operation\":{\"Deidentify\":{\"MaskConfig\":{}}}}]}'", + "NativeIaC": "```yaml\n# CloudFormation: apply data protection policy to mask secrets in a log group\nResources:\n LogGroup:\n Type: AWS::Logs::LogGroup\n Properties:\n LogGroupName: \n # Critical: Enables masking of detected credentials at egress so secrets aren't exposed\n DataProtectionPolicy: |\n {\"Statement\":[{\"DataIdentifier\":[\"arn:aws:dataprotection::aws:data-identifier/Credentials\"],\"Operation\":{\"Audit\":{\"FindingsDestination\":{}}}},{\"DataIdentifier\":[\"arn:aws:dataprotection::aws:data-identifier/Credentials\"],\"Operation\":{\"Deidentify\":{\"MaskConfig\":{}}}}]}\n```", + "Other": "1. In AWS Console, go to CloudWatch > Logs > Log groups and open \n2. Select the Data protection tab and click Create policy\n3. Under Managed data identifiers, select Credentials (or AwsSecretKey if listed)\n4. Click Activate data protection to save\n5. Re-ingest or generate new logs to ensure sensitive data is masked", + "Terraform": "```hcl\n# Apply a CloudWatch Logs data protection policy to mask secrets\nresource \"aws_cloudwatch_log_group\" \"log_group\" {\n name = \"\"\n\n # Critical: Masks detected credentials so secrets aren't visible and the check passes\n data_protection_policy = jsonencode({\n Statement = [\n {\n DataIdentifier = [\n \"arn:aws:dataprotection::aws:data-identifier/Credentials\"\n ]\n Operation = { Audit = { FindingsDestination = {} } }\n },\n {\n DataIdentifier = [\n \"arn:aws:dataprotection::aws:data-identifier/Credentials\"\n ]\n Operation = { Deidentify = { MaskConfig = {} } }\n }\n ]\n })\n}\n```" }, "Recommendation": { - "Text": "It is recommended that sensitive information is not logged to CloudWatch logs. Alternatively, sensitive data may be masked using a protection policy", - "Url": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/mask-sensitive-log-data.html" + "Text": "Avoid logging **secrets** via application sanitization and data minimization. Apply CloudWatch data protection policies to audit and mask sensitive patterns. Enforce *least privilege* for log readers and restrict `logs:Unmask`. Rotate exposed keys, reduce retention, and monitor findings to validate controls.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_group_no_secrets_in_logs" } }, "Categories": [ "secrets" ], - "Tags": { - "Tag1Key": "value", - "Tag2Key": "value" - }, "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_not_publicly_accessible/cloudwatch_log_group_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_not_publicly_accessible/cloudwatch_log_group_not_publicly_accessible.metadata.json index 18ab76d4d8..671edbca22 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_not_publicly_accessible/cloudwatch_log_group_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_not_publicly_accessible/cloudwatch_log_group_not_publicly_accessible.metadata.json @@ -1,32 +1,38 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_group_not_publicly_accessible", - "CheckTitle": "Ensure that CloudWatch Log Groups are not publicly accessible", + "CheckTitle": "CloudWatch Log Group is not publicly accessible", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability", + "TTPs/Initial Access/Unauthorized Access", + "Effects/Data Exposure" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:ses:region:account-id:log-group/log_group_name", + "ResourceIdTemplate": "", "Severity": "high", "ResourceType": "Other", - "Description": "This check ensures that no CloudWatch Log Groups are publicly accessible by checking for resource policies that allow access from any entity (Principal: '*'). Publicly exposed log groups pose a serious security risk as sensitive log data could be accessed by unauthorized parties.", - "Risk": "Publicly accessible CloudWatch Log Groups can expose sensitive information, leading to data breaches or unauthorized access. It is important to ensure that log groups are only accessible by trusted entities.", - "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html", + "Description": "**CloudWatch Log Groups** with resource policies that grant access to any principal are identified. Statements using `Principal:\"*\"` or wildcard `Resource` that reference a log group ARN indicate that the log group is exposed through a public policy.", + "Risk": "Public access to log groups enables unauthorized reading of logs, revealing secrets and operational metadata, harming **confidentiality**. If broad actions are allowed, attackers can modify subscriptions or logs, undermining **integrity** and disrupting **availability** of audit evidence.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html" + ], "Remediation": { "Code": { "CLI": "aws logs delete-resource-policy --policy-name ", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "NativeIaC": "```yaml\nResources:\n :\n Type: AWS::Logs::ResourcePolicy\n Properties:\n PolicyName: \n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Principal:\n AWS: \"\" # FIX: restrict to specific account (not *) to prevent public access\n Action: logs:PutSubscriptionFilter\n Resource: \"arn:aws:logs:::destination:\"\n```", + "Other": "1. Open the CloudWatch console\n2. Go to Logs > Resource policies\n3. Select the policy that exposes your log groups (Principal set to \"*\" or Resource \"*\")\n4. Click Delete and confirm", + "Terraform": "```hcl\nresource \"aws_cloudwatch_log_resource_policy\" \"\" {\n policy_name = \"\"\n policy_document = jsonencode({\n Version = \"2012-10-17\"\n Statement = [{\n Effect = \"Allow\"\n Principal = { AWS = \"\" } # FIX: restrict Principal (not \"*\") to avoid public access\n Action = \"logs:PutSubscriptionFilter\"\n Resource = \"arn:aws:logs:::destination:\"\n }]\n })\n}\n```" }, "Recommendation": { - "Text": "Ensure that CloudWatch Log Groups are not publicly accessible. Review and remove any resource policies that allow public access (Principal: '*') to log groups.", - "Url": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html" + "Text": "Remove public access from log group resource policies. Replace `Principal:\"*\"` and `Resource:\"*\"` with narrowly scoped principals and specific ARNs. Grant only necessary actions, apply conditions to constrain use, and enforce **least privilege** and **separation of duties** with regular policy reviews.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_group_not_publicly_accessible" } }, "Categories": [ - "internet-exposed" + "internet-exposed", + "identity-access" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json index cb7f378eef..30d0f57049 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json @@ -1,31 +1,45 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_group_retention_policy_specific_days_enabled", - "CheckTitle": "Check if CloudWatch Log Groups have a retention policy of specific days.", + "CheckTitle": "CloudWatch log group has a retention policy of at least the configured minimum days or never expires", "CheckType": [ - "Data Retention" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls (USA)", + "Software and Configuration Checks/Industry and Regulatory Standards/PCI-DSS", + "Software and Configuration Checks/Industry and Regulatory Standards/SOC 2" ], "ServiceName": "cloudwatch", - "SubServiceName": "logs", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "SubServiceName": "", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsLogsLogGroup", - "Description": "Check if CloudWatch Log Groups have a retention policy of specific days.", - "Risk": "If log groups have a low retention policy of less than specific days, crucial logs and data can be lost.", - "RelatedUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Logs.html", + "Description": "**CloudWatch Log Groups** are assessed for a retention period at or above the configured threshold (e.g., `365` days) or for being set to **never expire**. Log groups with shorter retention are identified.", + "Risk": "Short log retention erodes audit evidence. Adversaries can wait out the window, creating gaps in detection, forensics, and compliance reporting. This degrades the **availability** of historical logs and the **integrity** of incident timelines.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/cloudwatch-logs-retention-period.html", + "https://boto3.amazonaws.com/v1/documentation/api/1.26.93/reference/services/logs/client/put_retention_policy.html", + "https://medium.com/pareture/aws-cloudwatch-log-group-retention-periods-bb8a2fb9c358", + "https://www.blinkops.com/blog/cloudwatch-retention", + "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Logs.html" + ], "Remediation": { "Code": { "CLI": "aws logs put-retention-policy --log-group-name --retention-in-days ", - "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_13#cloudformation", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_13", - "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_13#terraform" + "NativeIaC": "```yaml\n# CloudFormation: set retention on a CloudWatch Log Group\nResources:\n :\n Type: AWS::Logs::LogGroup\n Properties:\n LogGroupName: \"\"\n RetentionInDays: # Critical: sets log retention to the required minimum to pass the check\n```", + "Other": "1. In the AWS Console, go to CloudWatch > Log groups\n2. Select the target log group\n3. In the Expire events after/Retention column, click the current value\n4. Choose a retention value >= or select Never expire\n5. Click Save", + "Terraform": "```hcl\n# Set retention on a CloudWatch Log Group\nresource \"aws_cloudwatch_log_group\" \"\" {\n name = \"\"\n retention_in_days = # Critical: set to at least the required minimum to pass the check\n}\n```" }, "Recommendation": { - "Text": "Add Log Retention policy of specific days to log groups. This will persist logs and traces for a long time.", - "Url": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Logs.html" + "Text": "Define a minimum retention baseline (e.g., `>=365` days) aligned to legal and investigative needs. Apply it consistently with documented exceptions. Automate enforcement, monitor changes, and restrict who can modify retention under **least privilege** and **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_group_retention_policy_specific_days_enabled" } }, - "Categories": [], + "Categories": [ + "logging", + "forensics-ready" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json index 2e83147050..20c96defd2 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json @@ -1,31 +1,39 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled", - "CheckTitle": "Ensure a log metric filter and alarm exist for AWS Config configuration changes.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for AWS Config configuration changes", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "TTPs/Defense Evasion" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for AWS Config configuration 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", + "Description": "CloudTrail logs in **CloudWatch Logs** are inspected for a metric filter and alarm that track **AWS Config configuration changes**, specifically `StopConfigurationRecorder`, `DeleteDeliveryChannel`, `PutDeliveryChannel`, and `PutConfigurationRecorder` events from `config.amazonaws.com`.", + "Risk": "Without alerting on **AWS Config changes**, actions like `StopConfigurationRecorder` or `DeleteDeliveryChannel` can silently suspend recording and delivery.\n\nThis degrades the **integrity** and **availability** of configuration audit data, enabling undetected changes and delaying incident response.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_9", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_9#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for AWS Config changes\nResources:\n ConfigChangeMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n FilterPattern: \"{($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder))}\" # Critical: detects AWS Config configuration change events\n MetricTransformations:\n - MetricName: aws_config_changes_metric # Critical: metric used by the alarm\n MetricNamespace: CISBenchmark\n MetricValue: \"1\"\n\n ConfigChangeAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: aws_config_changes_alarm\n MetricName: aws_config_changes_metric # Critical: ties alarm to the metric filter\n Namespace: CISBenchmark\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n Period: 300\n Statistic: Sum\n Threshold: 1 # Critical: alarm on first occurrence\n```", + "Other": "1. Open the CloudWatch console and go to Logs > Log groups\n2. Select the CloudTrail log group that receives trail events\n3. Create a metric filter with pattern:\n {($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder))}\n - Metric name: aws_config_changes_metric\n - Namespace: CISBenchmark\n - Value: 1\n4. From the created metric filter, choose Create alarm\n5. Set: Sum, Period 5 minutes, Threshold >= 1, Evaluation periods 1\n6. Create the alarm (actions/notifications optional)", + "Terraform": "```hcl\n# CloudWatch Logs metric filter for AWS Config changes\nresource \"aws_cloudwatch_log_metric_filter\" \"config_change\" {\n name = \"aws_config_changes_metric\"\n log_group_name = \"\"\n pattern = \"{($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder))}\" # Critical: detects AWS Config configuration change events\n\n metric_transformation {\n name = \"aws_config_changes_metric\" # Critical: metric used by the alarm\n namespace = \"CISBenchmark\"\n value = \"1\"\n }\n}\n\n# Alarm for the above metric\nresource \"aws_cloudwatch_metric_alarm\" \"config_change\" {\n alarm_name = \"aws_config_changes_alarm\"\n metric_name = \"aws_config_changes_metric\" # Critical: ties alarm to the metric filter\n namespace = \"CISBenchmark\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n period = 300\n statistic = \"Sum\"\n threshold = 1 # Critical: alarm on first occurrence\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Create a **CloudWatch Logs metric filter and alarm** for `config.amazonaws.com` events (`StopConfigurationRecorder`, `DeleteDeliveryChannel`, `PutDeliveryChannel`, `PutConfigurationRecorder`). Route CloudTrail to Logs, notify responders, and enforce **least privilege** and **separation of duties** on Config changes to prevent abuse.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json index e624cfbf78..ce5cf6c67b 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json @@ -1,31 +1,41 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled", - "CheckTitle": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for CloudTrail configuration changes", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices", + "TTPs/Defense Evasion" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for CloudTrail configuration 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", + "Description": "**CloudTrail logs** include a **metric filter** for trail configuration events (`CreateTrail`, `UpdateTrail`, `DeleteTrail`, `StartLogging`, `StopLogging`) with an associated **CloudWatch alarm** to alert on matches.\n\nEvaluates the presence of this filter-and-alarm monitoring.", + "Risk": "Absent this monitoring, logging can be stopped or altered without notice, eroding visibility.\n\nThat enables covert activity and data exfiltration without audit evidence, harming confidentiality, the integrity of records, and the availability of reliable logs for detection and forensics.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_5", + "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_5#fix---buildtime" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_5", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_5#fix---buildtime" + "NativeIaC": "```yaml\nResources:\n CloudTrailCfgMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: # CRITICAL: CloudTrail log group to monitor\n FilterPattern: \"{($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging)}\" # CRITICAL: Detects CloudTrail config changes\n MetricTransformations:\n - MetricName: # CRITICAL: Metric created by the filter\n MetricNamespace: \n MetricValue: \"1\"\n\n CloudTrailCfgAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n MetricName: # CRITICAL: Alarm uses metric from filter\n Namespace: \n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS Console, go to CloudWatch > Log groups and open the log group used by CloudTrail\n2. Create metric filter: Actions > Create metric filter\n - Filter pattern: {($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging)}\n - Metric name: , Namespace: , Value: 1\n - Create metric filter\n3. From the Metric filters tab, select the new filter and choose Create alarm\n - Threshold: Greater/Equal 1, Period: 5 minutes, Evaluation periods: 1\n - Create alarm", + "Terraform": "```hcl\nresource \"aws_cloudwatch_log_metric_filter\" \"cfg\" {\n name = \"\"\n log_group_name = \"\" # CRITICAL: CloudTrail log group\n pattern = \"{($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging)}\" # CRITICAL: Detects CloudTrail config changes\n\n metric_transformation {\n name = \"\" # CRITICAL: Metric created by filter\n namespace = \"\"\n value = \"1\"\n }\n}\n\nresource \"aws_cloudwatch_metric_alarm\" \"cfg\" {\n metric_name = \"\" # CRITICAL: Uses metric from filter\n namespace = \"\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Implement a **metric filter** for trail configuration events and a linked **alarm** that notifies response channels.\n\nApply **least privilege** and **separation of duties** for trail changes, add **defense in depth** with centralized logging and validation, and regularly test that alerts fire.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json index 8c2f9e4778..0ea837c1cd 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json @@ -1,31 +1,44 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_authentication_failures", - "CheckTitle": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures.", + "CheckTitle": "Account has a CloudWatch Logs metric filter and alarm for AWS Management Console authentication failures", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "TTPs/Initial Access", + "TTPs/Credential Access" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures.", - "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", + "Description": "CloudWatch Logs metric filter and alarm for **AWS Management Console authentication failures**, sourced from CloudTrail (`eventName=ConsoleLogin`, `errorMessage=\"Failed authentication\"`).\n\nIdentifies whether these failures are converted into a metric and actively monitored by an alarm.", + "Risk": "Absent visibility into failed console logins enables undetected **brute-force** and **credential-stuffing** attempts, extending attacker dwell time.\n\nSuccessful guesses can grant console access, risking data confidentiality, configuration integrity, and availability through destructive changes.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://www.intelligentdiscovery.io/controls/cloudwatch/cloudwatch-alarm-signin-failures", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/console-sign-in-failures-alarm.html", + "https://newsletter.simpleaws.dev/p/cloudtrail-cloudwatch-logs-login-detection-alert" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_6", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_6#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Metric filter and alarm for console authentication failures\nResources:\n MetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \"\"\n FilterPattern: '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' # Critical: matches failed console login events\n MetricTransformations:\n - MetricValue: \"1\"\n MetricNamespace: \"\" # Critical: creates metric namespace\n MetricName: \"\" # Critical: creates metric name\n\n Alarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n MetricName: \"\" # Critical: alarm targets metric from filter\n Namespace: \"\" # Critical: must match metric's namespace\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS Console, open CloudWatch\n2. Go to Logs > Log groups and select the CloudTrail log group receiving events\n3. Open the Metric filters tab > Create metric filter\n - Filter pattern: { ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\n - Assign any metric name and namespace, value 1, then create\n4. On the created metric filter, select it and choose Create alarm\n - Statistic: Sum, Period: 5 minutes, Threshold type: Static, Threshold: >= 1\n - Create the alarm", + "Terraform": "```hcl\n# Metric filter and alarm for console authentication failures\nresource \"aws_cloudwatch_log_metric_filter\" \"metric\" {\n name = \"\"\n log_group_name = \"\"\n pattern = \"{($.eventName = ConsoleLogin) && ($.errorMessage = \\\"Failed authentication\\\") }\" # Critical: detects failed console logins\n\n metric_transformation {\n name = \"\" # Critical: metric created by filter\n namespace = \"\" # Critical: metric namespace\n value = \"1\"\n }\n}\n\nresource \"aws_cloudwatch_metric_alarm\" \"alarm\" {\n metric_name = aws_cloudwatch_log_metric_filter.metric.metric_transformation[0].name # Critical: alarm references the filter's metric\n namespace = aws_cloudwatch_log_metric_filter.metric.metric_transformation[0].namespace # Critical: must match\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Implement a log metric filter for `ConsoleLogin` failures and attach a **CloudWatch alarm** with actionable notifications. Tune thresholds to reduce noise and route alerts to incident response.\n\nApply **least privilege** and enforce **MFA** to limit impact, and correlate alerts with source IP and user context.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_authentication_failures" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.metadata.json index bc182ce688..d2c7aa9f45 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.metadata.json @@ -1,31 +1,42 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_aws_organizations_changes", - "CheckTitle": "Ensure a log metric filter and alarm exist for AWS Organizations changes.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for AWS Organizations changes", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "TTPs/Privilege Escalation" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for AWS Organizations 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", + "Description": "**CloudWatch Logs** metric filters and alarms monitor **AWS Organizations** change events recorded by CloudTrail, including actions like `CreateAccount`, `AttachPolicy`, `MoveAccount`, and `UpdateOrganizationalUnit`.\n\nThe evaluation looks for a filter on the trail log group matching `organizations.amazonaws.com` events and an alarm linked to that metric.", + "Risk": "Without alerting on **AWS Organizations changes**, attackers or misconfigurations can silently alter governance, enabling unauthorized access and policy bypass. They could create/remove accounts, change or detach SCPs, or delete the organization, risking data exposure (C), privilege escalation (I), and service disruption (A).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://support.icompaas.com/support/solutions/articles/62000228348-ensure-a-log-metric-filter-and-alarm-exist-for-aws-organizations-changes", + "https://www.plerion.com/cloud-knowledge-base/ensure-aws-organizations-changes-are-monitored", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/organizations-changes-alarm.html" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/organizations-changes-alarm.html", - "Terraform": "" + "NativeIaC": "```yaml\n# CloudFormation: CloudWatch Logs metric filter and alarm for AWS Organizations changes\nResources:\n OrganizationsChangesMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n FilterPattern: '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CancelHandshake\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganization\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"EnableAllFeatures\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdateOrganizationalUnit\") || ($.eventName = \"UpdatePolicy\")) }' # Critical: matches AWS Organizations change events\n MetricTransformations:\n - MetricValue: \"1\"\n MetricNamespace: CISBenchmark\n MetricName: # Critical: creates metric used by the alarm\n\n OrganizationsChangesAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n MetricName: # Critical: alarms on the metric from the filter\n Namespace: CISBenchmark # Critical: must match the metric filter namespace\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. Open CloudWatch > Logs > Log groups and select the CloudTrail log group for your trail\n2. Choose Create metric filter and set Filter pattern to:\n { ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CancelHandshake\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganization\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"EnableAllFeatures\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdateOrganizationalUnit\") || ($.eventName = \"UpdatePolicy\")) }\n3. Assign a metric: Namespace = CISBenchmark, Metric name = OrganizationsChanges, Metric value = 1, then Create metric filter\n4. On the metric filter, select Create alarm; set Statistic = Sum, Period = 5 minutes, Threshold type = Static, Threshold = 1, Evaluation periods = 1; Create alarm", + "Terraform": "```hcl\n# CloudWatch Logs metric filter for AWS Organizations changes\nresource \"aws_cloudwatch_log_metric_filter\" \"organizations_changes\" {\n name = \"\"\n log_group_name = \"\"\n pattern = \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \\\"AcceptHandshake\\\") || ($.eventName = \\\"AttachPolicy\\\") || ($.eventName = \\\"CancelHandshake\\\") || ($.eventName = \\\"CreateAccount\\\") || ($.eventName = \\\"CreateOrganization\\\") || ($.eventName = \\\"CreateOrganizationalUnit\\\") || ($.eventName = \\\"CreatePolicy\\\") || ($.eventName = \\\"DeclineHandshake\\\") || ($.eventName = \\\"DeleteOrganization\\\") || ($.eventName = \\\"DeleteOrganizationalUnit\\\") || ($.eventName = \\\"DeletePolicy\\\") || ($.eventName = \\\"EnableAllFeatures\\\") || ($.eventName = \\\"EnablePolicyType\\\") || ($.eventName = \\\"InviteAccountToOrganization\\\") || ($.eventName = \\\"LeaveOrganization\\\") || ($.eventName = \\\"DetachPolicy\\\") || ($.eventName = \\\"DisablePolicyType\\\") || ($.eventName = \\\"MoveAccount\\\") || ($.eventName = \\\"RemoveAccountFromOrganization\\\") || ($.eventName = \\\"UpdateOrganizationalUnit\\\") || ($.eventName = \\\"UpdatePolicy\\\")) }\" # Critical: matches AWS Organizations change events\n\n metric_transformation {\n name = \"\" # Critical: metric created by the filter\n namespace = \"CISBenchmark\" # Critical: used by the alarm\n value = \"1\"\n }\n}\n\n# Alarm on the metric generated by the filter\nresource \"aws_cloudwatch_metric_alarm\" \"organizations_changes\" {\n alarm_name = \"\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n metric_name = \"\" # Critical: matches metric filter name\n namespace = \"CISBenchmark\" # Critical: matches metric filter namespace\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Send CloudTrail events to **CloudWatch Logs**, add a metric filter for `organizations.amazonaws.com` change events, and attach an alarm that notifies responders. Enforce **least privilege** and **separation of duties** for org admins, require MFA and approvals, and regularly test alerts to ensure timely detection and response.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_aws_organizations_changes" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json index 3161f181cf..ddc1dbbf1d 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json @@ -1,32 +1,37 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk", - "CheckTitle": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created KMS CMKs.", + "CheckTitle": "Account has a CloudWatch log metric filter and alarm for disabling or scheduled deletion of customer-managed KMS keys", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Denial of Service" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created KMS CMKs.", - "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", + "Description": "CloudTrail events delivered to CloudWatch are evaluated for a **metric filter and alarm** that monitor **KMS CMK state changes**, specifically `DisableKey` and `ScheduleKeyDeletion` from `kms.amazonaws.com`.", + "Risk": "Missing alerts on **CMK disablement or scheduled deletion** undermines **availability** and **integrity**: encrypted data may become undecryptable, backups unusable, and recovery impossible. Attackers or insiders can change key states unnoticed, causing outages and irreversible data loss.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/kms/latest/developerguide/deleting-keys-creating-cloudwatch-alarm.html" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_7", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_7#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Metric filter and alarm for KMS key disable/deletion\nResources:\n MetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n # CRITICAL: Detect KMS DisableKey or ScheduleKeyDeletion events from CloudTrail logs\n # This pattern is what the check looks for\n FilterPattern: '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }'\n MetricTransformations:\n - MetricValue: \"1\"\n MetricNamespace: CISBenchmark\n MetricName: disable_or_delete_cmk_changes_metric\n\n Alarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n # CRITICAL: Alarm on the metric created by the filter above\n MetricName: disable_or_delete_cmk_changes_metric\n Namespace: CISBenchmark\n Statistic: Sum\n Period: 300\n EvaluationPeriods: 1\n Threshold: 1\n ComparisonOperator: GreaterThanOrEqualToThreshold\n```", + "Other": "1. Open the AWS Console and go to CloudWatch > Log groups\n2. Select the CloudTrail log group that receives your trail events\n3. Choose Create metric filter\n4. In Filter pattern, paste: {($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\n5. Name the metric (e.g., disable_or_delete_cmk_changes_metric), set Namespace to CISBenchmark, Value to 1, then Create\n6. From the Metric filters tab, select the new filter and click Create alarm\n7. Set Statistic: Sum, Period: 5 minutes, Threshold type: Static, Threshold: 1, Comparison: Greater/Equal\n8. Create the alarm (notification actions optional and not required for pass)", + "Terraform": "```hcl\n# Metric filter for KMS DisableKey or ScheduleKeyDeletion\nresource \"aws_cloudwatch_log_metric_filter\" \"cmk\" {\n name = \"\"\n log_group_name = \"\" # CRITICAL: CloudTrail log group\n # CRITICAL: Detect KMS key disable or scheduled deletion events\n pattern = \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\"\n\n metric_transformation {\n name = \"disable_or_delete_cmk_changes_metric\" # CRITICAL: metric used by alarm\n namespace = \"CISBenchmark\"\n value = \"1\"\n }\n}\n\n# Alarm for the metric above\nresource \"aws_cloudwatch_metric_alarm\" \"cmk\" {\n alarm_name = \"\"\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n metric_name = \"disable_or_delete_cmk_changes_metric\" # CRITICAL: same metric name\n namespace = \"CISBenchmark\"\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Establish **CloudWatch metric filters and alarms** for `DisableKey` and `ScheduleKeyDeletion` CloudTrail events to enable rapid response.\n- Apply **least privilege** to KMS administration\n- Enforce **change control** and separation of duties\n- Use deletion waiting periods and monitor all regions", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk" } }, "Categories": [ - "encryption" + "logging" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json index ba7f04f9d4..1026944e89 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json @@ -1,31 +1,40 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_for_s3_bucket_policy_changes", - "CheckTitle": "Ensure a log metric filter and alarm exist for S3 bucket policy changes.", + "CheckTitle": "CloudWatch log metric filter and alarm exist for S3 bucket policy changes", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for S3 bucket policy 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", + "Description": "**CloudTrail** logs are assessed for a **CloudWatch metric filter** matching S3 bucket configuration changes (ACL, policy, CORS, lifecycle, replication; e.g., `PutBucketPolicy`, `DeleteBucketPolicy`) and for an associated **CloudWatch alarm**.", + "Risk": "Without alerting on S3 policy and ACL changes, unauthorized modifications can go unnoticed, weakening **confidentiality** and **integrity**. Misuse could expose buckets publicly, grant write/delete access, or alter replication paths, enabling data exfiltration and destructive actions.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://support.icompaas.com/support/solutions/articles/62000086674-ensure-a-log-metric-filter-and-alarm-exist-for-s3-bucket-policy-changes", + "https://www.tenable.com/audits/items/CIS_Amazon_Web_Services_Foundations_v5.0.0_L1.audit:8101350d6907e07863ac6748689b3e12" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_8", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_8#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: CloudWatch metric filter and alarm for S3 bucket policy changes\nResources:\n MetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: # Critical: CloudTrail log group to monitor\n FilterPattern: '{($.eventSource=s3.amazonaws.com) && (($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication))}' # Critical: detects S3 bucket policy changes\n MetricTransformations:\n - MetricName: \n MetricNamespace: \n MetricValue: \"1\"\n\n Alarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: \n Namespace: # Critical: must match metric filter\n MetricName: # Critical: must match metric filter\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. Open the CloudWatch console and go to Logs > Log groups.\n2. Select the CloudTrail log group that receives your trail events.\n3. Create metric filter:\n - Choose Create metric filter.\n - Filter pattern:\n ```\n {($.eventSource=s3.amazonaws.com) && (($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication))}\n ```\n - Set Metric name and Namespace (any values) and Metric value = 1. Save.\n4. From the Metric filters tab, select the new filter and choose Create alarm.\n5. Set: Statistic = Sum, Period = 5 minutes, Threshold type = Static, Condition = Greater/Equal, Threshold = 1, Evaluation periods = 1. Create alarm.", + "Terraform": "```hcl\n# CloudWatch metric filter for S3 bucket policy changes\nresource \"aws_cloudwatch_log_metric_filter\" \"\" {\n name = \"\"\n log_group_name = \"\"\n # Critical: detects S3 bucket policy changes from CloudTrail logs\n pattern = \"{($.eventSource=s3.amazonaws.com) && (($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication))}\"\n\n metric_transformation {\n name = \"\"\n namespace = \"\"\n value = \"1\"\n }\n}\n\n# Alarm on the metric filter\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n alarm_name = \"\"\n metric_name = \"\" # Critical: matches metric filter\n namespace = \"\" # Critical: matches metric filter\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Establish and maintain **metric filters** and **alarms** for S3 bucket policy, ACL, CORS, lifecycle, and replication changes. Route alerts to monitored channels and integrate with SIEM. Enforce **least privilege**, require change reviews, and use **defense in depth** to prevent and quickly detect unsafe bucket policy changes.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json index 9f41554dd0..4f6368ef7a 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json @@ -1,31 +1,40 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_policy_changes", - "CheckTitle": "Ensure a log metric filter and alarm exist for IAM policy changes.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for IAM policy changes", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "TTPs/Privilege Escalation" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for IAM policy 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", + "Description": "CloudWatch uses a metric filter and alarm to track **IAM policy changes** recorded by CloudTrail (e.g., `CreatePolicy`, `DeletePolicy`, version changes, inline policy edits, policy attach/detach). This finding reflects whether that filter and an associated alarm are present on the trail's log group.", + "Risk": "Absent alerting on **IAM policy changes**, privilege modifications can go unnoticed, enabling **privilege escalation**, hidden backdoors, or permission revocations. This threatens **confidentiality** and **integrity**, and may impact **availability** if critical access is removed or misconfigured.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://www.clouddefense.ai/compliance-rules/cis-v140/monitoring/cis-v140-4-4", + "https://www.intelligentdiscovery.io/controls/cloudwatch/cloudwatch-alarm-iam-policy-change" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_4", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_4#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for IAM policy changes\nResources:\n IAMPolicyChangeMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: # IMPORTANT: CloudTrail log group to monitor\n # CRITICAL: Pattern matching IAM policy change events required by the check\n FilterPattern: '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}'\n MetricTransformations:\n - MetricName: # CRITICAL: Metric created from filter\n MetricNamespace: CISBenchmark # CRITICAL: Namespace for the metric\n MetricValue: \"1\"\n\n IAMPolicyChangeAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: \n # CRITICAL: Alarm on the metric created above when >= 1 event occurs\n MetricName: \n Namespace: CISBenchmark\n Statistic: Sum\n Period: 300\n EvaluationPeriods: 1\n Threshold: 1\n ComparisonOperator: GreaterThanOrEqualToThreshold\n```", + "Other": "1. Open the CloudWatch console > Logs > Log groups and select the CloudTrail log group\n2. Create metric filter:\n - Filter pattern: {($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\n - Metric name: \n - Namespace: CISBenchmark\n - Metric value: 1\n3. On the Metric filters tab, select the new filter and choose Create alarm\n4. Set: Statistic=Sum, Period=5 minutes, Threshold type=Static, Greater/Equal, Threshold=1, Evaluation periods=1\n5. Create the alarm", + "Terraform": "```hcl\n# Terraform: Metric filter and alarm for IAM policy changes\nresource \"aws_cloudwatch_log_metric_filter\" \"\" {\n name = \"\"\n log_group_name = \"\" # CloudTrail log group\n\n # CRITICAL: Pattern matching IAM policy change events required by the check\n pattern = \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\"\n\n metric_transformation {\n name = \"\" # CRITICAL: Metric created from filter\n namespace = \"CISBenchmark\" # CRITICAL: Namespace for the metric\n value = \"1\"\n }\n}\n\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n alarm_name = \"\"\n # CRITICAL: Alarm on the metric when >= 1 event occurs\n metric_name = aws_cloudwatch_log_metric_filter..metric_transformation[0].name\n namespace = aws_cloudwatch_log_metric_filter..metric_transformation[0].namespace\n statistic = \"Sum\"\n period = 300\n evaluation_periods = 1\n threshold = 1\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Create a metric filter for IAM policy create/update/delete and attach/detach events with an **alarm** to notify responders.\n- Enforce **least privilege** and separation of duties for policy changes\n- Require approvals and central logging across Regions/accounts\n- Integrate alerts with incident response", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_policy_changes" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json index 71956eb37b..b7e4fd5469 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json @@ -1,31 +1,46 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_root_usage", - "CheckTitle": "Ensure a log metric filter and alarm exist for usage of root account.", + "CheckTitle": "Account has a CloudWatch Logs metric filter and alarm for root account usage", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/AWS Security Best Practices", + "TTPs/Privilege Escalation" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for usage of root account.", - "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", + "Description": "**CloudTrail** logs in CloudWatch include a metric filter for **root account activity** (`{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }`) and a linked CloudWatch alarm that triggers when the filter matches.", + "Risk": "Without alerting on **root activity**, full-privilege actions can proceed unnoticed, impacting:\n- confidentiality via data access/exfiltration\n- integrity via policy/config tampering\n- availability via deletions or shutdowns\nDelayed detection increases blast radius and persistence.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/root-account-usage-alarm.html", + "https://asecure.cloud/a/root_account_login/", + "https://support.icompaas.com/support/solutions/articles/62000083624-ensure-a-log-metric-filter-and-alarm-exist-for-usage-of-root-account", + "https://www.intelligentdiscovery.io/controls/cloudwatch/cloudwatch-alarm-root-account-usage", + "https://aws.amazon.com/blogs/security/how-to-receive-notifications-when-your-aws-accounts-root-access-keys-are-used/", + "https://www.tenable.com/audits/items/CIS_Amazon_Web_Services_Foundations_v1.5.0_L1.audit:000adfb028a1475075a6b5d2117f53f4" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_3", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_3#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for root account usage\nResources:\n RootUsageMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \"\"\n FilterPattern: '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' # CRITICAL: detects root user actions not invoked by services\n MetricTransformations:\n - MetricValue: \"1\"\n MetricNamespace: \"\" # CRITICAL: metric namespace used by the alarm\n MetricName: \"\" # CRITICAL: metric name used by the alarm\n\n RootUsageAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n MetricName: \"\" # CRITICAL: alarms on the metric created by the filter\n Namespace: \"\"\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS console, open CloudWatch > Logs > Log groups and select the CloudTrail log group\n2. Go to Metric filters > Create metric filter\n3. For Filter pattern, enter: { $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\n4. Click Next, set any Filter name, set Metric namespace and Metric name, set Metric value to 1, then Create metric filter\n5. Select the new metric filter and click Create alarm\n6. Set Period to 5 minutes, Statistic to Sum, Threshold type Static with value 1, Evaluation periods 1, then Create alarm", + "Terraform": "```hcl\n# CloudWatch Logs metric filter for root account usage\nresource \"aws_cloudwatch_log_metric_filter\" \"\" {\n name = \"\"\n log_group_name = \"\"\n pattern = \"{ $.userIdentity.type = \\\"Root\\\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \\\"AwsServiceEvent\\\" }\" # CRITICAL: detects root user actions\n\n metric_transformation {\n name = \"\" # CRITICAL: metric used by the alarm\n namespace = \"\"\n value = \"1\"\n }\n}\n\n# Alarm on the root usage metric\nresource \"aws_cloudwatch_metric_alarm\" \"\" {\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n metric_name = \"\" # CRITICAL: matches metric filter\n namespace = \"\"\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Enable real-time alerts for **root activity** using a log metric filter and a high-priority alarm with notifications.\n\nReduce exposure: enforce **least privilege**, keep root for *break-glass* with MFA, disable root access keys, and route alerts into incident response for **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_root_usage" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json index 9fb416859b..f5d6182540 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json @@ -1,31 +1,41 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_security_group_changes", - "CheckTitle": "Ensure a log metric filter and alarm exist for security group changes.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for security group changes", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for security group 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", + "Description": "**CloudTrail** events for **security group configuration changes** are monitored using a **CloudWatch Logs metric filter** with an associated **alarm**. The filter targets actions like `AuthorizeSecurityGroupIngress/Egress`, `RevokeSecurityGroupIngress/Egress`, `CreateSecurityGroup`, and `DeleteSecurityGroup` to surface any security group modifications.", + "Risk": "Without alerting on **security group changes**, unauthorized or mistaken rules can expose services to the Internet, enabling brute force and lateral movement (**confidentiality, integrity**). Deletions or restrictive edits can break connectivity (**availability**). Delayed detection increases attacker dwell time and impact.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://support.icompaas.com/support/solutions/articles/62000084030-ensure-a-log-metric-filter-and-alarm-exist-for-security-group-changes", + "https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Alarm-On-Logs.html", + "https://asecure.cloud/a/cwalarm_securitygroup_changes/" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_10", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_10#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for Security Group changes\nResources:\n MetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n # Critical: Matches Security Group change events required by the check\n # This publishes a metric when these events appear in CloudTrail logs\n FilterPattern: '{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }'\n MetricTransformations:\n - MetricName: \n MetricNamespace: \n MetricValue: \"1\"\n\n Alarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n # Critical: Alarm on the metric to satisfy the requirement\n MetricName: \n Namespace: \n Statistic: Sum\n Period: 300\n EvaluationPeriods: 1\n Threshold: 1\n ComparisonOperator: GreaterThanOrEqualToThreshold\n```", + "Other": "1. Open the CloudWatch console > Logs > Log groups, and select the CloudTrail log group\n2. Create metric filter with this pattern:\n { ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\n3. Assign metric: name , namespace , value 1, then create the filter\n4. From the metric filter, choose Create alarm and set: Statistic Sum, Period 5 minutes, Threshold type Static, Greater/Equal 1, Evaluation periods 1, then create the alarm", + "Terraform": "```hcl\n# Metric filter for Security Group changes\nresource \"aws_cloudwatch_log_metric_filter\" \"sg\" {\n name = \"\"\n log_group_name = \"\"\n # Critical: Matches Security Group change events required by the check\n pattern = \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\"\n\n metric_transformation {\n name = \"\"\n namespace = \"\"\n value = \"1\"\n }\n}\n\n# Alarm for the above metric\nresource \"aws_cloudwatch_metric_alarm\" \"sg\" {\n alarm_name = \"\"\n # Critical: Alarm on the SG change metric to pass the control\n metric_name = \"\"\n namespace = \"\"\n statistic = \"Sum\"\n period = 300\n evaluation_periods = 1\n threshold = 1\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Establish real-time alerts for **security group modifications** by sending CloudTrail to CloudWatch, creating metric filters and alarms, and notifying responders.\n- Enforce **least privilege** on SG changes\n- Use change management and tagging\n- Centralize logs, test alarms, and maintain runbooks\n- Layer with NACLs and WAF for **defense in depth**", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_security_group_changes" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json index 249691eb79..d3146ae693 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json @@ -1,31 +1,45 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_sign_in_without_mfa", - "CheckTitle": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA.", + "CheckTitle": "CloudWatch log metric filter and alarm exist for Management Console sign-in without MFA", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "TTPs/Initial Access", + "Unusual Behaviors/User" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA.", - "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", + "Description": "**CloudTrail logs** in CloudWatch are assessed for a metric filter and alarm that detect console logins where `$.eventName = ConsoleLogin` and `$.additionalEventData.MFAUsed != \\\"Yes\\\"`.\n\nThis reflects whether alerting exists for sign-ins that occur without **MFA**.", + "Risk": "Without alerting on non-MFA console logins, successful use of stolen passwords can go **undetected**, enabling:\n- Unauthorized console access and IAM changes\n- Data exfiltration or deletion\n\nImpacts: loss of **confidentiality** and **integrity**, and potential **availability** disruption.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/console-sign-in-without-mfa.html", + "https://www.tenable.com/audits/items/CIS_Amazon_Web_Services_Foundations_v3.0.0_L1.audit:1957056ee174cc38502d5f5f1864333b", + "https://www.clouddefense.ai/compliance-rules/gdpr/data-protection/log-metric-filter-console-login-mfa", + "https://www.intelligentdiscovery.io/controls/cloudwatch/cloudwatch-alarm-no-mfa", + "https://support.icompaas.com/support/solutions/articles/62000083605-ensure-a-log-metric-filter-and-alarm-exist-for-management-console-sign-in-without-mfa" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_2", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_2#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for console sign-in without MFA\nResources:\n NoMFAConsoleSigninMetricFilter:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \"\"\n FilterPattern: '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' # CRITICAL: detects ConsoleLogin events without MFA\n MetricTransformations:\n - MetricName: \"\"\n MetricNamespace: \"\"\n MetricValue: \"1\" # CRITICAL: emits a metric on each match\n\n NoMFAConsoleSigninAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n MetricName: \"\" # CRITICAL: alarm uses the metric from the filter\n Namespace: \"\"\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n Period: 300\n Statistic: Sum\n Threshold: 1 # CRITICAL: alarm on first occurrence\n```", + "Other": "1. In AWS Console, go to CloudWatch > Logs > Log groups and open the CloudTrail log group\n2. Go to Metric filters > Create metric filter\n3. Set Filter pattern to: { ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\n4. Next > set Filter name, Metric namespace, Metric name; set Metric value = 1; Create metric filter\n5. Select the new filter > Create alarm\n6. Set Statistic = Sum, Period = 5 minutes, Threshold type = Static, Threshold = 1, Whenever >= 1; Next\n7. Skip actions if not needed, Name the alarm, Create alarm", + "Terraform": "```hcl\n# Create metric filter for console sign-in without MFA\nresource \"aws_cloudwatch_log_metric_filter\" \"nomfa\" {\n name = \"\"\n log_group_name = \"\"\n pattern = \"{ ($.eventName = \\\"ConsoleLogin\\\") && ($.additionalEventData.MFAUsed != \\\"Yes\\\") }\" # CRITICAL: detects ConsoleLogin without MFA\n\n metric_transformation {\n name = \"\"\n namespace = \"\"\n value = \"1\" # CRITICAL: emits a count per match\n }\n}\n\n# Alarm on the emitted metric\nresource \"aws_cloudwatch_metric_alarm\" \"nomfa\" {\n alarm_name = \"\"\n metric_name = aws_cloudwatch_log_metric_filter.nomfa.metric_transformation[0].name # CRITICAL: ties alarm to the metric\n namespace = aws_cloudwatch_log_metric_filter.nomfa.metric_transformation[0].namespace\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n period = 300\n statistic = \"Sum\"\n threshold = 1 # CRITICAL: alarm on first event\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Enforce **MFA** for all console-capable identities and maintain alerts for `ConsoleLogin` with `MFAUsed != \\\"Yes\\\"`.\n\nApply **least privilege**, route alarms to monitored channels, and tune for SSO to reduce noise. Test alarms regularly and review coverage as part of **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_sign_in_without_mfa" } }, - "Categories": [], + "Categories": [ + "logging", + "threat-detection" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json index 23313584da..a7e5253bfd 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json @@ -1,31 +1,44 @@ { "Provider": "aws", "CheckID": "cloudwatch_log_metric_filter_unauthorized_api_calls", - "CheckTitle": "Ensure a log metric filter and alarm exist for unauthorized API calls.", + "CheckTitle": "CloudWatch Logs metric filter and alarm exist for unauthorized API calls", "CheckType": [ - "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "TTPs/Initial Access/Unauthorized Access" ], "ServiceName": "cloudwatch", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:cloudwatch:region:account-id:certificate/resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudWatchAlarm", - "Description": "Ensure a log metric filter and alarm exist for unauthorized API calls.", - "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", + "Description": "**CloudWatch Logs** for CloudTrail include a metric filter that matches unauthorized API errors (`$.errorCode=\"*UnauthorizedOperation\"` or `$.errorCode=\"AccessDenied*\"`) and a linked alarm that triggers when events match the filter.", + "Risk": "Without alerting on **unauthorized API calls**, permission probing and failed access by compromised identities can go unnoticed. Attackers can enumerate services, pivot, and attempt privilege escalation, threatening data **confidentiality** and **integrity**.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", + "https://asecure.cloud/a/unauthorized_api_calls/", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudWatchLogs/authorization-failures-alarm.html", + "https://www.tenable.com/policies/[type]/AC_AWS_0559", + "https://www.intelligentdiscovery.io/controls/cloudwatch/cloudwatch-unauthorized-api-calls", + "https://support.icompaas.com/support/solutions/articles/62000083561-ensure-a-log-metric-filter-and-alarm-exist-for-unauthorized-api-calls" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_1", - "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_1#fix---buildtime" + "NativeIaC": "```yaml\n# CloudFormation: Create metric filter and alarm for unauthorized API calls\nResources:\n MetricFilterUnauthorized:\n Type: AWS::Logs::MetricFilter\n Properties:\n LogGroupName: \n FilterPattern: '{($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\")}' # Critical: detects unauthorized/denied API calls\n MetricTransformations:\n - MetricName: unauthorized_api_calls_metric\n MetricNamespace: CISBenchmark\n MetricValue: \"1\"\n\n AlarmUnauthorized:\n Type: AWS::CloudWatch::Alarm\n Properties:\n ComparisonOperator: GreaterThanOrEqualToThreshold\n EvaluationPeriods: 1\n MetricName: unauthorized_api_calls_metric # Critical: alarm on the metric from the filter\n Namespace: CISBenchmark\n Period: 300\n Statistic: Sum\n Threshold: 1\n```", + "Other": "1. In the AWS Console, open CloudWatch > Logs > Log groups and select the CloudTrail log group\n2. Go to Metric filters > Create metric filter\n3. Set Filter pattern to: {($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\")}\n4. Name the metric unauthorized_api_calls_metric, set Namespace to CISBenchmark, Value to 1, then create\n5. Select the new metric filter and click Create alarm\n6. Set Statistic: Sum, Period: 5 minutes, Threshold type: Static, Threshold: 1, Evaluation periods: 1\n7. Create the alarm", + "Terraform": "```hcl\n# Terraform: Metric filter and alarm for unauthorized API calls\nresource \"aws_cloudwatch_log_metric_filter\" \"unauthorized\" {\n name = \"unauthorized_api_calls_metric\"\n log_group_name = \"\"\n pattern = \"{($.errorCode = \\\"*UnauthorizedOperation\\\") || ($.errorCode = \\\"AccessDenied*\\\")}\" # Critical: detects unauthorized/denied API calls\n\n metric_transformation {\n name = \"unauthorized_api_calls_metric\"\n namespace = \"CISBenchmark\"\n value = \"1\"\n }\n}\n\nresource \"aws_cloudwatch_metric_alarm\" \"unauthorized\" {\n comparison_operator = \"GreaterThanOrEqualToThreshold\"\n evaluation_periods = 1\n metric_name = \"unauthorized_api_calls_metric\" # Critical: alarm on the metric from the filter\n namespace = \"CISBenchmark\"\n period = 300\n statistic = \"Sum\"\n threshold = 1\n}\n```" }, "Recommendation": { - "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html" + "Text": "Enable real-time **alerting** by adding a CloudWatch Logs metric filter for unauthorized errors (`*UnauthorizedOperation`, `AccessDenied*`) and associating it with an alarm that notifies responders.\n- Enforce **least privilege** to reduce noise\n- Integrate with IR tooling for **defense in depth**", + "Url": "https://hub.prowler.com/check/cloudwatch_log_metric_filter_unauthorized_api_calls" } }, - "Categories": [], + "Categories": [ + "threat-detection", + "logging" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Logging and Monitoring"