Skip to content

Lab 08 — Edge protection (WAF on an ALB)

📝 Guide written, not run yet 🧭 Infrastructure Security 💲 ≈ $0.05 / hour
Services: AWS WAF, ALB, Lambda, CloudWatch Logs, Shield (concepts), Firewall Manager (concepts)

In one sentence

Put a web app behind an ALB, protect it with an AWS WAF web ACL, trigger each rule type yourself — IP set, custom path rule, managed rules, a managed group in Count mode and a rate-based rule — then find every decision in the WAF logs.

The idea

 your laptop (MY_IP) ──HTTP:80──► sec8-alb (internet-facing, 2 AZs, SG: port 80 from MY_IP only)
                                     │  ▲
                                     │  └── sec8-web-acl (REGIONAL), evaluated in priority order:
                                     │        0 block-ip-set      IP set sec8-blocked-ips      → Block
                                     │        1 block-admin-path  URI starts with /admin       → Block
                                     │        2 aws-common        AWSManagedRulesCommonRuleSet → Block
                                     │        3 aws-sqli-count    AWSManagedRulesSQLiRuleSet   → Count only
                                     │        4 rate-limit        > 10 req / 60 s per IP       → Block
                                     │        default action: Allow
                                     ▼            logs → CloudWatch Logs aws-waf-logs-sec8
                            target group sec8-tg ──► Lambda sec8-app (no EC2 needed)

What to expect when you run it

# Test Expected Rule
1 Normal page ✅ 200 default Allow
2 /admin/users ❌ 403 block-admin-path
3 /ADMIN (upper case) ❌ 403 LOWERCASE text transformation
4 <script>alert(1)</script> in a query arg ❌ 403 aws-common CrossSiteScripting_QUERYARGUMENTS
5 No User-Agent header ❌ 403 aws-common NoUserAgent_HEADER
6 id=1' OR '1'='1 ⚠️ 200 (!) aws-sqli-count — counts only
7 Own IP added to the IP set ❌ 403, back to 200 after removing it block-ip-set (updates need a LockToken)
8 60 requests in 60 s ⚠️ more than 10 × 200 first, then 403; allowed again once the window drops below the limit rate-limit (detection has a short delay)

In the logs: blocked requests carry terminatingRuleId; the SQLi request shows "action":"ALLOW" with a COUNT match inside ruleGroupList — exactly what it would have blocked. Sampled requests are kept 3 hours without logging.

Key lessons

  1. Priority order, first terminating action wins. Allow / Block / CAPTCHA / Challenge stop evaluation; Count records and continues; the default action applies last.
  2. Roll out managed groups in Count first, read the logs, then switch the override back to the group's own actions.
  3. Text transformations matter. Without LOWERCASE, /ADMIN walks past a /admin rule.
  4. SG = layer 3/4 (who can connect), WAF = layer 7 (what the request contains).

Exam notes

  • WAF attaches to ALB, CloudFront, API Gateway (REST), AppSync, Cognito user pools, App Runner, Verified Access — not NLB or EC2 directly.
  • Scope REGIONAL vs CLOUDFRONT; a CloudFront web ACL must be created in us-east-1.
  • WCU limit 1,500 per web ACL by default (more costs extra).
  • Logs → CloudWatch Logs, S3 or Firehose; name must start with aws-waf-logs-. Redact fields like Authorization / cookies.
  • Managed groups: CommonRuleSet (OWASP), KnownBadInputs, SQLi, Linux/Windows/PHP, AmazonIpReputationList, AnonymousIpList (VPN/Tor/hosting); paid: Bot Control, ATP (account takeover), ACFP (fake account creation).
  • Rate-based rules: 1/2/5/10-min windows, min limit 10; aggregate by IP, forwarded IP (X-Forwarded-For, spoofable), header, cookie, query arg; scope-down statement (e.g. only /login).
  • Shield Standard: free, automatic, L3/4. Shield Advanced: $3,000/month per org, 1-year commitment; SRT 24/7 (needs Business/Enterprise support), DDoS cost protection, automatic application-layer mitigation, WAF included for protected resources; protects EIPs, NLB, ALB, CloudFront, Route 53, Global Accelerator.
  • Best DDoS architecture: CloudFront + Route 53 at the edge, WAF on CloudFront, origin only reachable from CloudFront (OAC for S3; for ALB: CloudFront prefix list in the SG + secret header).
  • Firewall Manager: central WAF/Shield/SG/Network Firewall policies across the org (needs Config + Organizations); new accounts covered automatically. Network Firewall: stateful L3–L7 VPC firewall (Suricata rules, domain lists) for traffic not going through ALB/CloudFront.

Review questions

Question 1

Your API is attacked by a credential-stuffing bot hitting POST /login from thousands of IPs, a few requests each. Will a plain rate-based rule (limit 100 per IP) help? What would?

Show answer

No — each IP stays far below 100, so a per-IP rate rule never triggers. Use the ATP (Account Takeover Prevention) managed group on the login path (it checks stolen-credential lists and failed login patterns), plus Bot Control and CAPTCHA/Challenge actions; a rate rule with a scope-down on /login and a low limit, or aggregated on another key, adds a further layer.

Question 2

You want to deploy the SQLi managed rule group in production without risking false positives. How, and where do you check what it would have blocked?

Show answer

Add the group with its rule actions overridden to Count. Requests are still allowed, but matches are recorded: check the WAF logs (the COUNT entry in ruleGroupList / nonTerminatingMatchingRules), CloudWatch metrics per rule and sampled requests. Once you are sure it would only block bad traffic, remove the override so the group's Block actions apply.

Question 3

A web ACL is in us-east-2 but you can't select your CloudFront distribution. Why?

Show answer

CloudFront is global, so it needs a web ACL with scope CLOUDFRONT, which must be created in us-east-1. A REGIONAL web ACL in us-east-2 can only protect regional resources there (ALB, API Gateway, AppSync, Cognito…).

Question 4

Which Shield Advanced feature reimburses you for Auto Scaling/CloudFront charges caused by a DDoS? What else do you need to engage the Shield Response Team?

Show answer

DDoS cost protection (service credits for scaling charges from an attack on a protected resource). To use the SRT you need a Business or Enterprise Support plan, and you grant the SRT an IAM role so it can view and update your WAF/Shield configuration (proactive engagement is an optional extra).

Question 5

The ALB must only accept traffic that came through CloudFront. Name two controls.

Show answer

(1) Allow inbound on the ALB security group only from the CloudFront managed prefix list (com.amazonaws.global.cloudfront.origin-facing). (2) Have CloudFront add a secret custom header and only forward requests carrying it — via a WAF rule or an ALB listener rule (rotate the secret). The prefix list alone isn't enough: anyone's CloudFront distribution uses the same IPs.