AWS WAF
Web Application Firewall - Protect against common web exploits
π΅ Cost: WAF costs $5/month per Web ACL + $1/month per rule + $0.60 per million requests. AWS Managed Rules are free (included in rule count). Can add up for high-traffic sites. See aws.amazon.com/waf/pricing. Last verified: January 2026.
What is AWS WAF?
AWS WAF (Web Application Firewall) protects your web applications from common web exploits like SQL injection, cross-site scripting (XSS), and other OWASP Top 10 vulnerabilities. It sits in front of your ALB, CloudFront, or API Gateway.
When to Use WAF
- Protect against OWASP Top 10 vulnerabilities
- Block malicious bots and scrapers
- Rate limiting to prevent DDoS
- Geographic restrictions
- IP allowlist/blocklist
WAF Components
| Component | Purpose |
|---|---|
| Web ACL | Container for rules, associated with ALB/CloudFront |
| Rule | Condition + action (allow, block, count) |
| Rule Group | Collection of reusable rules |
| Managed Rules | Pre-built rules from AWS or partners |
| IP Set | List of IP addresses to allow/block |
WAF Architecture
Plain Text
Internet
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β AWS WAF (Web ACL) β
β βββ AWS Managed Rules β
β β βββ AWSManagedRulesCommonRuleSet
β β βββ AWSManagedRulesSQLiRuleSet β
β β βββ AWSManagedRulesKnownBadInputsRuleSet
β β β
β βββ Rate Limiting Rule β
β β βββ 2000 requests/5 min/IP β
β β β
β βββ Custom Rules β
β βββ Block specific IPs β
β βββ Geo-block certain countriesβ
βββββββββββββββββββββββββββββββββββββββ
β
βΌ
Application Load Balancer β ECS TasksAWS provides free managed rule groups that protect against common vulnerabilities:
| Rule Group | Protects Against | Recommended |
|---|---|---|
AWSManagedRulesCommonRuleSet | OWASP Top 10, XSS, command injection | Yes |
AWSManagedRulesSQLiRuleSet | SQL injection attacks | Yes |
AWSManagedRulesKnownBadInputsRuleSet | Known malicious patterns | Yes |
AWSManagedRulesAmazonIpReputationList | Known bad IPs (bots, spammers) | Yes |
AWSManagedRulesAnonymousIpList | VPNs, Tor, proxies | Optional |
AWSManagedRulesBotControlRuleSet | Bot traffic management | Paid add-on |
Start in Count Mode
Enable new rules in count mode first to monitor without blocking. Review CloudWatch metrics for false positives before switching to block mode.
HCL
# Web ACL for ALB
resource "aws_wafv2_web_acl" "main" {
name = "my-app-waf"
description = "WAF for my application"
scope = "REGIONAL" # Use "CLOUDFRONT" for CloudFront
default_action {
allow {}
}
# AWS Managed Rules - Common Rule Set
rule {
name = "AWSManagedRulesCommonRuleSet"
priority = 1
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "CommonRuleSetMetric"
sampled_requests_enabled = true
}
}
# AWS Managed Rules - SQL Injection
rule {
name = "AWSManagedRulesSQLiRuleSet"
priority = 2
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesSQLiRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "SQLiRuleSetMetric"
sampled_requests_enabled = true
}
}
# Rate limiting rule
rule {
name = "RateLimitRule"
priority = 3
action {
block {}
}
statement {
rate_based_statement {
limit = 2000
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "RateLimitMetric"
sampled_requests_enabled = true
}
}
# IP Blocklist (optional)
rule {
name = "IPBlocklist"
priority = 0
action {
block {}
}
statement {
ip_set_reference_statement {
arn = aws_wafv2_ip_set.blocklist.arn
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "IPBlocklistMetric"
sampled_requests_enabled = true
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "MyAppWAFMetric"
sampled_requests_enabled = true
}
tags = {
Environment = var.environment
}
}
# IP Set for blocklist
resource "aws_wafv2_ip_set" "blocklist" {
name = "ip-blocklist"
description = "Known bad IPs"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = [] # Add blocked IPs here
}
# Associate WAF with ALB
resource "aws_wafv2_web_acl_association" "main" {
resource_arn = aws_lb.main.arn
web_acl_arn = aws_wafv2_web_acl.main.arn
}WAF Pricing
Pricing Note
WAF pricing is consistent across regions. Always verify at aws.amazon.com/waf/pricing. Last verified: January 2026.
| Component | Cost |
|---|---|
| Web ACL | $5.00/month |
| Rule | $1.00/month each |
| Requests | $0.60 per million |
| AWS Managed Rules | Free (counts toward rule limit) |
| Bot Control | $10/month + $1/million requests |
Cost Example
Basic WAF setup with 5 rules and 10 million requests/month:
$5 (ACL) + $5 (5 rules) + $6 (10M requests) = ~$16/month
$5 (ACL) + $5 (5 rules) + $6 (10M requests) = ~$16/month