AWS WAF and Shield: DDoS Protection and Web Security
Running web applications on AWS without a proper perimeter defense is like leaving your front door wide open. AWS WAF (Web Application Firewall) and AWS Shield together provide a layered security model that stops SQL injection, cross-site scripting, volumetric DDoS floods, and sophisticated bot attacks before they ever reach your application code. This guide walks through every major feature — Web ACLs, managed rule groups, rate-based rules, Shield Advanced, Firewall Manager, and Bot Control — with real CloudFormation templates and Python automation examples you can use immediately.
Table of Contents
- AWS WAF Overview: Web ACLs, Rules, and WCU
- Rule Types: Managed, Rate-Based, and Custom
- WAF with CloudFront, ALB, API Gateway, AppSync, Cognito
- Building Custom Rules: IP Sets, Geo-Match, Regex, Size Constraints
- WAF Logging: Firehose, S3, and CloudWatch
- AWS Shield Standard vs Shield Advanced
- DDoS Attack Types and AWS Mitigations
- AWS Firewall Manager
- Bot Control and Fraud Control
- Cost Breakdown
- Frequently Asked Questions
AWS WAF Overview: Web ACLs, Rules, and WCU
AWS WAF inspects HTTP/HTTPS requests at layer 7 and allows you to block, allow, or count requests based on conditions you define. The top-level construct is a Web ACL (Access Control List), which is a container for an ordered list of rules and rule groups.
Every Web ACL has a default action — either ALLOW or BLOCK — that applies to any request that doesn't match any rule. Rules are evaluated in priority order (lower number = evaluated first). When a rule matches, WAF applies that rule's action (ALLOW, BLOCK, COUNT, or CAPTCHA) and stops evaluating further rules, unless the rule's action is COUNT.
Web ACL Capacity Units (WCU)
WAF enforces a capacity limit on each Web ACL measured in Web ACL Capacity Units (WCU). The default limit is 1,500 WCU per Web ACL (soft limit, can be increased). Each rule and rule group consumes WCU based on complexity:
- Simple string match rule: 1 WCU
- Regex match rule: 3–25 WCU depending on complexity
- SQL injection rule: 20 WCU
- AWS Managed Rule Group (Core): 700 WCU
- Bot Control (Common): 50 WCU, (Targeted): 100 WCU
Tracking WCU matters when you stack multiple managed rule groups plus custom rules. If you hit the 1,500 WCU ceiling you'll need to request a quota increase via Service Quotas.
Scope: Regional vs CloudFront
When creating a Web ACL, you choose either Regional (for ALB, API Gateway, AppSync, Cognito) or CloudFront (global scope, must be created in us-east-1). A CloudFront Web ACL is evaluated at the edge PoP closest to the user, which means your ALB never sees blocked traffic — a significant performance and cost advantage.
Rule Types: Managed, Rate-Based, and Custom
AWS Managed Rule Groups
AWS Managed Rules are curated, pre-built rule groups maintained by the AWS Threat Research Team. They're updated automatically when new attack patterns emerge without requiring any changes on your end.
The most commonly used managed rule groups:
- AWSManagedRulesCommonRuleSet — OWASP Top 10 protection: SQL injection, XSS, path traversal, log4j, Spring4Shell. 700 WCU. Start here.
- AWSManagedRulesKnownBadInputsRuleSet — Blocks requests matching known bad patterns: PROPFIND, null bytes, path traversal, log injection. 200 WCU.
- AWSManagedRulesSQLiRuleSet — Dedicated SQL injection detection, more aggressive than the common rule set. 200 WCU.
- AWSManagedRulesLinuxRuleSet — Linux-specific attack patterns like /etc/passwd traversal. 200 WCU.
- AWSManagedRulesAmazonIpReputationList — Blocks IPs associated with botnets, scanners, and malicious crawlers. 25 WCU.
- AWSManagedRulesAnonymousIpList — Blocks Tor exit nodes, VPN endpoints, and hosting providers that frequently originate attacks. 50 WCU.
Rate-Based Rules
Rate-based rules block IPs that exceed a request threshold within a 5-minute rolling window. The minimum threshold is 100 requests per 5 minutes. You can apply rate-based rules against the full request or aggregate by IP, forwarded IP, custom header value, HTTP method, or query string.
Common patterns:
- Global rate limit: 2,000 req/5min per IP — catches basic DDoS floods
- Login endpoint rate limit: 100 req/5min to
/api/login— prevents credential stuffing - Search endpoint rate limit: 500 req/5min to
/search— prevents scraping
Custom Rules
Custom rules let you write precise match conditions using IP sets, regex pattern sets, geo-match, string match, header inspection, and size constraints. These are covered in detail in the Custom Rules section below.
WAF with CloudFront, ALB, API Gateway, AppSync, Cognito
AWS WAF integrates with five AWS resources. You associate a Web ACL directly to the resource — no agent or SDK needed.
CloudFront
Associate a CloudFront-scoped Web ACL to your distribution. WAF evaluation happens at the edge, before the request is forwarded to the origin. Blocked requests never hit your ALB or EC2 — saving compute costs and preventing application-level DDoS impact. CloudFront passes the x-amzn-waf-action header to the origin so you can log the WAF decision.
Application Load Balancer (ALB)
For ALB, create a Regional Web ACL in the same region as the ALB. The association is a one-to-one relationship per ALB. If you have multiple ALBs across accounts, use Firewall Manager (covered later) to manage them centrally.
API Gateway REST API
Associate a Regional WAF Web ACL to a specific API Gateway stage (e.g., /prod). WAF evaluates every request to that stage. This is particularly useful for rate-limiting API consumers and blocking malformed JSON payloads before they hit Lambda.
AppSync GraphQL API
AppSync associations use the same Regional Web ACL as ALB. You can inspect the GraphQL query body using regex or string match rules to block deeply nested queries (GraphQL introspection abuse) or known malicious operation names.
Cognito User Pool
Associating WAF with a Cognito User Pool protects authentication flows — sign-up, sign-in, forgot-password — from credential stuffing and brute force. This is one of the most impactful uses of WAF rate-based rules since Cognito endpoints are publicly accessible.
Building Custom Rules: IP Sets, Geo-Match, Regex, Size Constraints
IP Sets
An IP set is a reusable list of IPv4 or IPv6 CIDR ranges. You reference the IP set from one or more rules. Maximum 10,000 addresses per IP set. IP sets can be updated independently of the Web ACL — useful for dynamic blocklists and allowlists updated by automation (see boto3 example below).
Geo-Match
Geo-match rules evaluate the two-letter country code of the request IP. Use cases: block all traffic except from specific countries (allowlist), block countries with high bot activity, route different rule chains based on geography.
Regex Pattern Sets
Regex pattern sets let you match against any part of the request: URI, query string, body (first 8 KB), single header, all headers, cookies, or the full request path. Maximum 10 patterns per set, each up to 200 characters. Patterns use the PCRE syntax subset supported by WAF (no lookaheads).
String Match
String match statements evaluate a specific component (URI, header, query string, body) against a literal string. Match types: EXACTLY, STARTS_WITH, ENDS_WITH, CONTAINS, CONTAINS_WORD. String matches cost 1–2 WCU versus 3–25 WCU for regex, so prefer string match when the condition allows it.
Size Constraint
Size constraint rules block requests where a specific component exceeds or is below a byte threshold. Common patterns:
- Block request bodies over 8 KB (prevents large payload injection)
- Block URIs over 2,048 bytes (prevents path traversal with long strings)
- Block query strings over 512 bytes
Code Example 1: WAF Web ACL CloudFormation Template
AWSTemplateFormatVersion: '2010-09-09'
Description: WAF Web ACL for ALB with managed rules + rate limiting
Resources:
# IP set for manual blocklist
BlockedIPSet:
Type: AWS::WAFv2::IPSet
Properties:
Name: techoral-blocked-ips
Scope: REGIONAL
IPAddressVersion: IPV4
Addresses: [] # populated via automation
# Regex pattern set - block suspicious user agents
SuspiciousUASet:
Type: AWS::WAFv2::RegexPatternSet
Properties:
Name: techoral-suspicious-ua
Scope: REGIONAL
RegularExpressionList:
- "(sqlmap|nikto|masscan|nmap|zgrab|nuclei|dirbuster)"
TechoralWebACL:
Type: AWS::WAFv2::WebACL
Properties:
Name: techoral-web-acl
Scope: REGIONAL
DefaultAction:
Allow: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: TechoralWebACL
Rules:
# Rule 1: Block manually blocked IPs (priority 0)
- Name: BlockListedIPs
Priority: 0
Action:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: BlockListedIPs
Statement:
IPSetReferenceStatement:
Arn: !GetAtt BlockedIPSet.Arn
# Rule 2: AWS IP Reputation List (priority 1)
- Name: AWSIPReputationList
Priority: 1
OverrideAction:
None: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: AWSIPReputationList
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesAmazonIpReputationList
# Rule 3: Core Rule Set (priority 2)
- Name: AWSCoreRuleSet
Priority: 2
OverrideAction:
None: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: AWSCoreRuleSet
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesCommonRuleSet
ExcludedRules:
# Exclude if your app sends large bodies
- Name: SizeRestrictions_BODY
# Rule 4: Known Bad Inputs (priority 3)
- Name: AWSKnownBadInputs
Priority: 3
OverrideAction:
None: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: AWSKnownBadInputs
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesKnownBadInputsRuleSet
# Rule 5: Rate limit per IP — 1000 req/5min (priority 4)
- Name: RateLimitPerIP
Priority: 4
Action:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: RateLimitPerIP
Statement:
RateBasedStatement:
Limit: 1000
AggregateKeyType: IP
# Rule 6: Tighter rate limit on login endpoint (priority 5)
- Name: LoginRateLimit
Priority: 5
Action:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: LoginRateLimit
Statement:
RateBasedStatement:
Limit: 100
AggregateKeyType: IP
ScopeDownStatement:
ByteMatchStatement:
SearchString: "/api/auth/login"
FieldToMatch:
UriPath: {}
TextTransformations:
- Priority: 0
Type: LOWERCASE
PositionalConstraint: STARTS_WITH
# Rule 7: Geo-block high-risk regions (priority 6)
- Name: GeoBlock
Priority: 6
Action:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: GeoBlock
Statement:
GeoMatchStatement:
CountryCodes: ["KP", "IR", "CU"]
# Rule 8: Block suspicious user agents (priority 7)
- Name: BlockSuspiciousUA
Priority: 7
Action:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: BlockSuspiciousUA
Statement:
RegexPatternSetReferenceStatement:
Arn: !GetAtt SuspiciousUASet.Arn
FieldToMatch:
SingleHeader:
Name: "user-agent"
TextTransformations:
- Priority: 0
Type: LOWERCASE
# Associate Web ACL to ALB
WebACLAssociation:
Type: AWS::WAFv2::WebACLAssociation
Properties:
ResourceArn: !Sub "arn:aws:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:loadbalancer/app/techoral-alb/XXXXXXXX"
WebACLArn: !GetAtt TechoralWebACL.Arn
Code Example 2: CLI — Create IP Set and Rate-Based Rule
# Create an IP set for known bad actors
aws wafv2 create-ip-set \
--name "techoral-blocked-ips" \
--scope REGIONAL \
--ip-address-version IPV4 \
--addresses "192.0.2.0/24" "198.51.100.44/32" \
--region us-east-1
# Output includes the IPSet ARN and LockToken — save these
# {
# "Summary": {
# "ARN": "arn:aws:wafv2:us-east-1:123456789012:regional/ipset/techoral-blocked-ips/abc123",
# "Id": "abc123",
# "LockToken": "token-xyz"
# }
# }
# List all Web ACLs in region
aws wafv2 list-web-acls \
--scope REGIONAL \
--region us-east-1
# Get current Web ACL configuration
aws wafv2 get-web-acl \
--name "techoral-web-acl" \
--scope REGIONAL \
--id "your-web-acl-id" \
--region us-east-1
# Create a standalone rate-based rule (via update-web-acl if adding to existing ACL)
# First get the lock token from get-web-acl, then call update-web-acl
# Check WAF sampled requests (last 3 hours, up to 500 samples)
aws wafv2 get-sampled-requests \
--web-acl-arn "arn:aws:wafv2:us-east-1:123456789012:regional/webacl/techoral-web-acl/id" \
--rule-metric-name "RateLimitPerIP" \
--scope REGIONAL \
--time-window "StartTime=2026-06-06T00:00:00Z,EndTime=2026-06-06T03:00:00Z" \
--max-items 50 \
--region us-east-1
# Get WAF metrics from CloudWatch
aws cloudwatch get-metric-statistics \
--namespace "AWS/WAFV2" \
--metric-name "BlockedRequests" \
--dimensions Name=WebACL,Value=techoral-web-acl Name=Region,Value=us-east-1 Name=Rule,Value=RateLimitPerIP \
--start-time 2026-06-06T00:00:00Z \
--end-time 2026-06-06T12:00:00Z \
--period 3600 \
--statistics Sum \
--region us-east-1
Code Example 3: Python boto3 — Dynamic IP Blocklist Update
This script reads a list of malicious IPs from an S3 file (e.g., threat feed output) and updates a WAF IP set. It handles the LockToken requirement — WAF uses optimistic locking to prevent concurrent updates from overwriting each other.
import boto3
import json
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
wafv2 = boto3.client('wafv2', region_name='us-east-1')
s3 = boto3.client('s3')
IPSET_NAME = 'techoral-blocked-ips'
IPSET_ID = 'abc123-your-ipset-id'
SCOPE = 'REGIONAL'
S3_BUCKET = 'techoral-security-feeds'
S3_KEY = 'blocklist/latest.json'
MAX_IPS = 10000 # WAF IP set hard limit
def load_blocklist_from_s3():
"""Load IP CIDR list from S3 threat feed."""
response = s3.get_object(Bucket=S3_BUCKET, Key=S3_KEY)
data = json.loads(response['Body'].read())
# Expect: {"blocked_ips": ["1.2.3.4/32", "5.6.7.0/24", ...]}
ips = data.get('blocked_ips', [])
logger.info(f"Loaded {len(ips)} IPs from S3")
return ips[:MAX_IPS] # Trim to WAF limit
def get_ipset_lock_token():
"""Fetch current IP set and its LockToken."""
response = wafv2.get_ip_set(
Name=IPSET_NAME,
Scope=SCOPE,
Id=IPSET_ID
)
return response['IPSet'], response['LockToken']
def update_ipset(addresses: list[str]):
"""Update WAF IP set with new address list."""
_, lock_token = get_ipset_lock_token()
if not addresses:
logger.warning("Empty address list — skipping update to avoid clearing IP set")
return
response = wafv2.update_ip_set(
Name=IPSET_NAME,
Scope=SCOPE,
Id=IPSET_ID,
LockToken=lock_token,
Addresses=addresses
)
logger.info(f"IP set updated. New LockToken: {response['NextLockToken']}")
return response
def add_ips_to_blocklist(new_ips: list[str]):
"""Merge new IPs into the existing blocklist."""
current_ipset, lock_token = get_ipset_lock_token()
existing = set(current_ipset['Addresses'])
merged = list(existing | set(new_ips))
if len(merged) > MAX_IPS:
logger.warning(f"Blocklist would exceed {MAX_IPS} IPs. Trimming oldest.")
merged = merged[:MAX_IPS]
response = wafv2.update_ip_set(
Name=IPSET_NAME,
Scope=SCOPE,
Id=IPSET_ID,
LockToken=lock_token,
Addresses=merged
)
logger.info(f"Added {len(new_ips)} IPs. Total: {len(merged)}")
return response
def sync_from_threat_feed():
"""Full sync: replace IP set content with latest S3 threat feed."""
addresses = load_blocklist_from_s3()
update_ipset(addresses)
logger.info("Blocklist sync complete")
if __name__ == '__main__':
# Example 1: Full sync from threat feed
sync_from_threat_feed()
# Example 2: Add specific IPs detected by your SIEM
siem_detections = ["203.0.113.42/32", "203.0.113.99/32"]
add_ips_to_blocklist(siem_detections)
WAF Logging: Firehose, S3, and CloudWatch
WAF logging writes a JSON record for every evaluated request (ALLOW, BLOCK, COUNT). The log destination must have a name starting with aws-waf-logs-.
Logging Destinations
- Kinesis Data Firehose — Lowest latency. Firehose can forward to S3 (most common), Splunk, Elasticsearch, or Redshift. Stream name must start with
aws-waf-logs-. - Amazon S3 — Direct S3 logging (no Firehose needed). Files arrive in
AWSLogs/<account>/WAFLogs/<region>/<web-acl-name>/<year>/<month>/<day>/. Files are gzipped JSON. - Amazon CloudWatch Logs — Best for near-real-time dashboards and alerting. Log group name must start with
aws-waf-logs-. Higher cost at scale but easiest for quick analysis with Insights.
Log Filtering
Log filtering lets you reduce log volume (and cost) by only logging specific requests. You can configure filters on action (ALLOW / BLOCK / COUNT / CAPTCHA), label match (rule that matched), and combination of conditions. For example, only log blocked requests and requests matching the rate-based rule:
# Enable WAF logging to CloudWatch Logs with filtering
aws wafv2 put-logging-configuration \
--logging-configuration '{
"ResourceArn": "arn:aws:wafv2:us-east-1:123456789012:regional/webacl/techoral-web-acl/id",
"LogDestinationConfigs": [
"arn:aws:logs:us-east-1:123456789012:log-group:aws-waf-logs-techoral"
],
"LoggingFilter": {
"DefaultBehavior": "DROP",
"Filters": [
{
"Behavior": "KEEP",
"Conditions": [
{
"ActionCondition": {
"Action": "BLOCK"
}
}
],
"Requirement": "MEETS_ANY"
},
{
"Behavior": "KEEP",
"Conditions": [
{
"LabelNameCondition": {
"LabelName": "awswaf:managed:aws:amazon-ip-list:AWSManagedIPReputationList"
}
}
],
"Requirement": "MEETS_ANY"
}
]
},
"RedactedFields": [
{
"SingleHeader": { "Name": "authorization" }
},
{
"SingleHeader": { "Name": "cookie" }
}
]
}' \
--region us-east-1
The RedactedFields configuration replaces sensitive header values with REDACTED in logs — important for PCI-DSS and GDPR compliance.
AWS Shield Standard vs Shield Advanced
Shield Standard
Shield Standard is included at no extra charge with every AWS account. It provides automatic protection against common and most frequently occurring infrastructure-level (Layer 3 and 4) DDoS attacks: UDP floods, SYN floods, DNS reflection, and NTP amplification. Shield Standard protects CloudFront, Route 53, Global Accelerator, EC2, and Elastic Load Balancers automatically.
Standard gives you:
- Always-on traffic monitoring and detection
- Automatic inline attack mitigations (no rules to configure)
- Network flow logging in CloudWatch during active mitigation
Shield Advanced
Shield Advanced costs $3,000/month per organization (flat fee, covers all resources under one account family) plus data transfer OUT fees. It adds:
- Enhanced L3/L4 protection — larger volumetric attacks, more sophisticated SYN floods, protocol reflection attacks
- L7 DDoS detection — automatic baseline learning of your application's traffic pattern; creates WAF rules automatically during active attacks
- AWS Shield Response Team (SRT) access — 24/7 DDoS experts available via AWS Support (Business or Enterprise tier required)
- Cost protection — AWS credits your account for any EC2, ELB, CloudFront, Route 53 scaling charges caused by a DDoS attack
- CloudWatch enhanced metrics — DDoSDetected, DDoSAttackBitsPerSecond, DDoSAttackPacketsPerSecond, AttackVector
- Proactive engagement — SRT contacts you proactively if they detect an active attack on your resources
- Attack forensics reports — Post-event reports in the Shield console showing attack vector, peak size, and duration
DDoS Attack Types and AWS Mitigations
Volumetric Attacks (Layer 3/4)
Volumetric attacks flood your network pipe with traffic — UDP amplification, DNS reflection, ICMP floods. Attack sizes range from a few Gbps to 2+ Tbps. AWS mitigates these at the network edge before traffic reaches your region. Shield Standard handles attacks up to hundreds of Gbps; Shield Advanced handles multi-terabit attacks via AWS's network scrubbing centers.
State Exhaustion Attacks (Layer 4)
SYN floods and TCP connection exhaustion attacks exploit the stateful nature of TCP to overwhelm connection tables on load balancers and servers. AWS ALB and NLB track connection state in the AWS network fabric, which is far more resilient than software-based firewalls. Shield monitors connection rate metrics and activates SYN proxy protections automatically.
Application Layer Attacks (Layer 7)
HTTP floods, Slowloris, RUDY (R-U-Dead-Yet), and GET/POST floods target application-layer resources. A botnet sending legitimate-looking HTTP requests at high volume won't be stopped by Layer 3/4 mitigations. This is where WAF rate-based rules, Bot Control, and Shield Advanced's L7 detection (which auto-creates temporary WAF rules) come in.
When Shield Advanced detects an L7 DDoS, it analyzes the attack traffic, identifies distinguishing characteristics (user agent, request path, header pattern), and automatically creates a WAF BLOCK rule scoped to the attack traffic. This rule is temporary and removed once the attack subsides. The SRT monitors the process in real time.
AWS Firewall Manager: Centralized WAF Policy Management
Firewall Manager lets you define WAF policies once and apply them automatically across all accounts in an AWS Organization. It requires:
- AWS Organizations with all features enabled
- A designated Firewall Manager administrator account
- AWS Config enabled in all accounts and regions
How Policies Work
A Firewall Manager WAF policy specifies:
- A base set of rules to be prepended or appended to every account's Web ACL
- Resource scope: which resource types (ALB, API Gateway, CloudFront) and which accounts/OUs to apply to
- Enforcement mode: Firewall Manager can auto-remediate (create missing Web ACLs) or just report non-compliance
When Firewall Manager creates Web ACLs in member accounts, those accounts can add their own rules in the middle — between the Firewall Manager prepended rules and appended rules. This enables central governance while allowing team-level customization.
Common Enterprise Patterns
- Prepend: AWSManagedRulesAmazonIpReputationList + Anonymous IP List (enforced everywhere)
- Each team: adds their application-specific rules and rate limits in the middle
- Append: Geo-block certain countries organization-wide
Bot Control and Fraud Control Managed Rule Groups
Bot Control
AWS WAF Bot Control is a managed rule group that detects and manages bot traffic. It offers two levels:
- Common bot protection (50 WCU, $10/month) — Categorizes traffic using signature-based detection. Labels bots as verified (search engines, monitors), category (scraper, scanner, content fetcher), and browser automation. You write rules to act on these labels.
- Targeted bot protection (100 WCU, $10/month extra) — Adds browser fingerprinting via a JavaScript challenge (like CAPTCHA without a puzzle) and CAPTCHA puzzles for higher-confidence bot detection. Effective against headless browsers like Puppeteer and Playwright that bypass signature detection.
Bot Control adds labels to requests like awswaf:managed:aws:bot-control:bot:category:scraper. You then write custom rules that match on these labels and apply BLOCK, CAPTCHA, or COUNT actions depending on your use case. For example, you might COUNT scraper bots on marketing pages but BLOCK them on checkout pages.
Account Takeover Prevention (ATP)
ATP is a fraud control managed rule group focused on credential stuffing against login endpoints. It:
- Inspects login form submissions and checks credentials against a compromised credential database (AWS maintains this)
- Tracks failed login attempts per IP and per username across requests
- Labels requests with
awswaf:managed:aws:atp:aggregate:volumetric:ip:highwhen threshold exceeded - Integrates with Cognito and custom login endpoints via request body inspection
Account Creation Fraud Prevention (ACFP)
ACFP detects bulk account creation (fake account farms used for abuse, promotional code exploitation, fraud). It analyzes registration form submissions, detects common fake-identity patterns, and labels high-risk registration attempts so you can challenge or block them.
Cost Breakdown
| Resource | Cost |
|---|---|
| Web ACL | $5.00/month per Web ACL |
| Rule or Rule Group | $1.00/month per rule |
| Requests evaluated | $0.60 per million requests |
| AWS Managed Rule Group | $1.00/month per rule group (in addition to the per-rule charge) |
| Bot Control Common | $10.00/month + $1.00 per million requests |
| Bot Control Targeted | Additional $10.00/month on top of Common |
| ATP (Account Takeover Prevention) | $10.00/month + $1.00 per 1,000 login attempts analyzed |
| ACFP (Account Creation Fraud Prevention) | $10.00/month + $2.00 per 1,000 registration attempts analyzed |
| Shield Standard | Free |
| Shield Advanced | $3,000/month per organization + data transfer OUT charges at standard rate |
| Firewall Manager (WAF policy) | $100.00/month per policy per region |
Frequently Asked Questions
What is the difference between WAF on CloudFront vs WAF on ALB?
CloudFront WAF evaluates at the edge — blocked requests never reach your VPC, so you save on data transfer and ALB compute. ALB WAF runs in your region after the request traverses CloudFront. If you use CloudFront as your CDN, always put WAF there. If you expose ALB directly (no CloudFront), put WAF on the ALB. You can also stack both — WAF at CloudFront blocks most attacks, WAF at ALB provides defense-in-depth.
Can WAF block all DDoS attacks?
No. WAF operates at Layer 7 (HTTP/HTTPS). It cannot stop Layer 3/4 volumetric attacks that saturate the network pipe before HTTP packets are assembled. Shield Standard and Shield Advanced handle those. For comprehensive coverage you need both: WAF for application-layer threats, Shield for network-layer floods.
How do I avoid false positives with the Core Rule Set?
Start with all rules in COUNT mode for 2 weeks. Review sampled requests in the WAF console and CloudWatch metrics. Identify which rules are triggering on legitimate traffic. Exclude those specific rules by name in the ManagedRuleGroupStatement ExcludedRules list. Common false positives come from SizeRestrictions_BODY (if your app accepts large JSON payloads) and CrossSiteScripting_BODY (if your CMS or rich text editor posts HTML).
Does Shield Advanced automatically create WAF rules during an attack?
Yes. Shield Advanced has an automatic application layer DDoS mitigation feature. When enabled on a resource, Shield monitors your application's traffic baseline and automatically creates temporary WAF BLOCK rules during active L7 attacks. These rules target the specific attack characteristics and are removed when the attack ends. You must associate a WAF Web ACL to the protected resource for this to work.
Is Shield Advanced worth $3,000/month for a startup?
For most startups, no. Shield Standard + WAF Core Rule Set + rate-based rules covers the vast majority of attacks. Shield Advanced makes sense when: (a) you're in a DDoS-targeted industry (gaming, finance, crypto, news media), (b) downtime costs exceed $3,000/hour, (c) you need SRT access for compliance or SLA reasons, or (d) you're running a large multi-account org where the cost protection benefit can recoup fees in a single event.
How do I test WAF rules without breaking production?
Use COUNT action instead of BLOCK when first adding rules. COUNT evaluates the rule and increments the metric but does not block the request. Monitor the CloudWatch metric for false positives. When confident, switch to BLOCK. For new managed rule groups, use OverrideAction: Count in the CloudFormation template, then switch to OverrideAction: None (which means "use the group's own actions") after validation.