Skip to main content
emnode / learn
Compliance Medium severity

AWS Security Hub · ELB

ELB.16: ALBs should be associated with a WAF web ACL

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub ELB.16 check?

ELB.16 fails when an internet-facing Application Load Balancer has no AWS WAF web ACL associated with it. The control recognises both WAFv2 and the legacy WAF Classic association.

Why does ELB.16 matter?

Without a web ACL, every request — including SQL injection, path traversal, bad bots and L7 floods — reaches your application untouched, leaving your code as the only line of defence. A WAF in front of the ALB filters common attack patterns and known-bad sources before they hit your targets, and AWS managed rule groups give broad coverage within minutes.

How do I fix ELB.16?

  1. Find ALBs with no associated web ACL using the wafv2 list-resources-for-web-acl and elbv2 APIs.
  2. Create a WAFv2 web ACL with the appropriate REGIONAL scope and add the AWS managed core and known-bad-inputs rule groups.
  3. Roll the rules out in count mode first to spot false positives, then switch to block.
  4. Associate the web ACL to the ALB and enforce association on new ALBs via IaC or a Config rule.

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 ELB.16 a false positive?

Use REGIONAL scope for ALBs — a CloudFront-scoped (global) web ACL cannot be associated with a regional ALB and will leave the finding open.

Part of the learning path Lock down access
  • ELB.1 ALB serves HTTP without redirecting to HTTPS
  • ELB.2 CLB SSL/HTTPS listeners should use ACM certs
  • ELB.3 CLB listeners should use HTTPS/TLS termination
  • ELB.4 ALB accepts malformed HTTP headers
  • ELB.5 Load balancers are not writing access logs
  • ELB.6 Load balancers can be deleted by accident
  • ELB.7 CLBs should have connection draining
  • ELB.8 CLB SSL listeners should use strong policy
  • ELB.9 CLBs should have cross-zone balancing
  • ELB.10 CLBs should span multiple AZs
  • ELB.12 ALB desync mitigation mode
  • ELB.13 A single-AZ load balancer is a data-plane single point of failure