S3 bucket policy changes alarm
Check ID: aws-cw-008
AWS-CW-008 is an AWS security check performed by cloud-audit, an open-source AWS security scanner. Checks if a CloudWatch metric filter and alarm exist to detect S3 bucket policy changes (PutBucketPolicy, PutBucketAcl, DeleteBucketPolicy). Without this monitoring, S3 data exposure goes undetected.
Why it matters
S3 bucket policy changes are the most common vector for accidental public data exposure. Between 2017 and 2023, hundreds of high-profile data breaches resulted from misconfigured S3 bucket policies, including the 2017 Verizon breach (6M customer records), the 2019 Capital One breach (100M records), and the 2020 Estee Lauder breach (440M records). A single PutBucketPolicy call can make a private bucket publicly readable in seconds. Real-time alerting on bucket policy changes enables security teams to immediately revert unauthorized changes before data scanners like GrayhatWarfare index the exposed content. Even with S3 Block Public Access enabled at the account level, monitoring policy changes catches attempts that might succeed if the block is ever disabled.
Common causes
S3 bucket policies are modified frequently during development as teams iterate on access patterns, making it easy for a permissive policy to slip through code review. Infrastructure-as-code templates with variable-substituted bucket policies can accidentally produce public policies when variables are misconfigured. Cross-account access patterns often require broad bucket policies that teams copy from documentation examples without scoping down.
Detection
Run cloud-audit to detect this issue:
pip install cloud-audit
cloud-audit scan -R The -R flag includes remediation details for every finding, including this one.
Remediation: AWS CLI
# Create metric filter:
aws logs put-metric-filter \
--log-group-name <CLOUDTRAIL_LOG_GROUP> \
--filter-name CIS-4.8 \
--filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = DeleteBucketPolicy)) }' \
--metric-transformations metricName=CIS-4-8,metricNamespace=CISBenchmark,metricValue=1
# Create alarm:
aws cloudwatch put-metric-alarm \
--alarm-name CIS-4.8 \
--metric-name CIS-4-8 \
--namespace CISBenchmark \
--statistic Sum --period 300 --threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--evaluation-periods 1 \
--alarm-actions <SNS_TOPIC_ARN> Remediation: Terraform
resource "aws_cloudwatch_log_metric_filter" "cis_4_8" {
name = "CIS-4.8"
log_group_name = aws_cloudwatch_log_group.cloudtrail.name
pattern = "{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = DeleteBucketPolicy)) }"
metric_transformation {
name = "CIS-4-8"
namespace = "CISBenchmark"
value = "1"
}
}
resource "aws_cloudwatch_metric_alarm" "cis_4_8" {
alarm_name = "CIS-4.8"
metric_name = "CIS-4-8"
namespace = "CISBenchmark"
statistic = "Sum"
period = 300
threshold = 1
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = 1
alarm_actions = [aws_sns_topic.alerts.arn]
} Compliance mapping
This check maps to CIS 4.8 in the CIS AWS Foundations Benchmark. The CIS Benchmark provides prescriptive guidance for configuring security options for a subset of AWS services.
This check is part of cloud-audit - install with pip install cloud-audit
Related article
CIS AWS v3.0 in 60 Seconds: Automate Compliance with Terraform →