AWS Security Hub · WAF
WAF.6: WAF Classic global rules should have a condition
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub WAF.6 check?
WAF.6 checks AWS WAF Classic global rules (`AWS::WAF::Rule`, the CloudFront-scoped tier served by the `waf` API). It reports FAILED when a global rule contains zero conditions. It is the global twin of WAF.2, which checks the Regional `AWS::WAFRegional::Rule`.
Why does WAF.6 matter?
An empty rule matches nothing, so every request passes through it without inspection regardless of the action set. A rule named `BlockBadBots` with no conditions blocks no bad bots. The exposure isn't a visible gap: it's a control that looks present on the dashboard and at the CloudFront edge while doing nothing, so operators reasonably assume the edge is protected when it isn't.
How do I fix WAF.6?
- Inventory the empty global rules using the `aws waf` API (global WAF Classic answers only on the us-east-1 endpoint).
- Decide complete-or-delete for each rule.
- Attach a real condition via the change-token workflow, or remove the empty rule.
- Bake rule completion into the definition of done so empty rules stop appearing.
Remediation script · bash
# Attach the AWS Managed Rules common baseline to an empty web ACL, in Count mode.
# update-web-acl REPLACES the entire Rules array, so supply the full desired set and the current LockToken.
aws wafv2 update-web-acl \
--scope REGIONAL --name public-alb-waf --id a1b2c3d4-0000-1111-2222-3333 \
--lock-token e4f5g6h7 --default-action Allow={} \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=public-alb-waf \
--rules '[{"Name":"AWS-CommonRuleSet","Priority":0,"Statement":{"ManagedRuleGroupStatement":{"VendorName":"AWS","Name":"AWSManagedRulesCommonRuleSet"}},"OverrideAction":{"Count":{}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"AWS-CommonRuleSet"}}]'
# Associate a baseline web ACL with an unprotected API Gateway stage (the resource ARN is the stage, not the API).
aws wafv2 associate-web-acl \
--web-acl-arn arn:aws:wafv2:us-east-1:111122223333:regional/webacl/prod-api-baseline/1a2b3c4d \
--resource-arn arn:aws:apigateway:us-east-1::/restapis/a1b2c3d4e5/stages/prod
# Protect a Network Firewall from accidental deletion.
aws network-firewall update-firewall-delete-protection \
--firewall-name prod-egress-inspection --delete-protection Full walkthrough (console steps, edge cases and verification) in the lesson Protect APIs and edge with WAF.
Is WAF.6 a false positive?
Like its Regional twin WAF.2, this control fails any global rule with an empty condition set, including one kept deliberately hollow as a staging placeholder, for instance a CloudFront-scoped rule provisioned ahead of the conditions that will populate it, or one whose predicates are temporarily cleared while a blocklist is rebuilt. A global rule that is not attached to any web ACL inspects no edge traffic and is inert in isolation, yet still reports FAILED because WAF.6 checks only that conditions exist. When the empty rule is a sanctioned, unattached placeholder, document it and suppress the finding (or mark it NOT_AFFECTED with a Security Hub automation rule) instead of bolting on a filler condition just to clear the check.
More WAF controls
- WAF.1 WAF Classic global web ACL logging
- 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.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