AWS Security Hub · WAF
WAF.1: WAF Classic global web ACL logging
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub WAF.1 check?
WAF.1 is a periodic check on AWS WAF Classic global web ACLs (`AWS::WAF::WebACL`, the CloudFront-scoped kind). It reports FAILED when the web ACL has no logging configuration — when it isn't pointed at a Kinesis Data Firehose delivery stream to capture the requests it allows, blocks, and counts.
Why does WAF.1 matter?
A web ACL enforcing rules with no record of its decisions can't be audited. When a customer reports a legitimate request being blocked, or a security team needs to reconstruct an attack, the WAF logs are the primary evidence — and without logging every decision evaporates the moment it's made. It also maps to NIST AU-2/AU-3/AU-12 and PCI DSS 10.4.2, so an unlogged web ACL is a compliance gap on its own.
How do I fix WAF.1?
- Provision a Kinesis Data Firehose stream in us-east-1 whose name begins with the required `aws-waf-logs-` prefix.
- Identify the silent global web ACLs via the `aws waf` API (global WAF Classic is served only from the us-east-1 endpoint).
- Attach the logging configuration to each web ACL, redacting sensitive fields such as Authorization headers.
- Confirm records flow to the stream and the control flips to PASSED on the next evaluation.
Remediation script · bash
# Load balancer: enable access logs to a dedicated, log-delivery-permissioned bucket.
aws elbv2 modify-load-balancer-attributes \
--load-balancer-arn "$LB_ARN" \
--attributes \
Key=access_logs.s3.enabled,Value=true \
Key=access_logs.s3.bucket,Value=acme-elb-logs-eu-west-1 \
Key=access_logs.s3.prefix,Value=prod-api
# WAF web ACL: attach logging (Firehose/log-group name must start with aws-waf-logs-),
# redact credentials, and keep only blocked requests to cap volume.
aws wafv2 put-logging-configuration --logging-configuration \
ResourceArn="$WEBACL_ARN",LogDestinationConfigs="arn:aws:firehose:us-east-1:111122223333:deliverystream/aws-waf-logs-prod",RedactedFields=[{SingleHeader={Name=authorization}}]
# Network Firewall: enable ALERT logs to CloudWatch and FLOW logs to S3.
aws network-firewall update-logging-configuration --firewall-name prod-egress-fw \
--logging-configuration 'LogDestinationConfigs=[{LogType=ALERT,LogDestinationType=CloudWatchLogs,LogDestination={logGroup=/netfw/prod-egress-fw/alert}}]'
# Route 53: log group MUST be in us-east-1, then attach the query logging config.
aws logs create-log-group --log-group-name /aws/route53/customer-portal --region us-east-1
aws route53 create-query-logging-config --hosted-zone-id Z0J1K4M2X8N9A1 \
--cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/customer-portal Full walkthrough (console steps, edge cases and verification) in the lesson Enable network and edge logging (LB, WAF, firewall, DNS).
Is WAF.1 a false positive?
Global WAF Classic only answers on the us-east-1 endpoint, so omitting `--region us-east-1` makes auditing commands return confusing errors that can look like a missing resource rather than a logging gap.
More WAF controls
- WAF.2 WAF Classic regional rules should have a condition
- WAF.3 WAF Classic regional rule groups should have a rule
- WAF.4 WAF Classic regional web ACLs should have a rule
- WAF.6 WAF Classic global rules should have a condition
- WAF.7 WAF Classic global rule groups should have a rule
- WAF.8 WAF Classic global web ACLs should have a rule
- WAF.10 WAFv2 web ACLs should have a rule or rule group
- WAF.11 WAFv2 web ACL logging should be enabled