Skip to content
Back to skills

Aws Waf

ASecurity

Expert agent for AWS WAF v2. Covers WebACLs, rule groups, managed rule groups (AWS + marketplace), rate-based rules, IP sets, regex pattern sets, Bot Control, Fraud Control ATP, and integration with ALB, CloudFront, API Gateway, and AppSync. WHEN: \"AWS WAF\", \"WebACL\", \"AWS managed rules\", \"WAF rule group\", \"Bot Control\", \"ATP\", \"AWS Shield\", \"waf.tf\", \"aws_wafv2\", \"WAF ALB\", \"WAF CloudFront\".

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 24, 2026
devopsjavascriptpythonrustgojavaphpshellsqlawsterraform

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add chrishuffman5/domain-expert --skill aws-waf --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Aws Waf?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Aws Waf
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-aws-waf/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-aws-waf)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: aws-waf
description: "Expert agent for AWS WAF v2. Covers WebACLs, rule groups, managed rule groups (AWS + marketplace), rate-based rules, IP sets, regex pattern sets, Bot Control, Fraud Control ATP, and integration with ALB, CloudFront, API Gateway, and AppSync. WHEN: \"AWS WAF\", \"WebACL\", \"AWS managed rules\", \"WAF rule group\", \"Bot Control\", \"ATP\", \"AWS Shield\", \"waf.tf\", \"aws_wafv2\", \"WAF ALB\", \"WAF CloudFront\"."
license: MIT
---

# AWS WAF

This skill covers AWS WAF v2 (WAFv2), AWS's managed web application firewall service. It covers WebACL configuration, managed rule groups, custom rules, Bot Control, Fraud Control, and integration with AWS services (ALB, CloudFront, API Gateway, AppSync, Cognito).

## How to Approach Tasks

1. **Identify the protected resource type:**
   - **CloudFront distribution** -- Global scope WebACL (us-east-1 region)
   - **ALB / API Gateway / AppSync** -- Regional scope WebACL (same region as resource)
   - **Cognito User Pool** -- Regional scope
2. **Identify the concern:**
   - **Setup** -- Creating and associating WebACL
   - **Rule management** -- Managed vs. custom rules, rule priority
   - **Bot protection** -- Bot Control managed rule group
   - **Fraud prevention** -- Account takeover protection (ATP)
   - **Infrastructure as code** -- Terraform, CloudFormation
3. **Consider cost** -- AWS WAF charges per WebACL, per rule group, and per million requests processed.

## AWS WAF Architecture

```
CloudFront / ALB / API Gateway / AppSync / Cognito
            ↓
        WebACL (associated to resource)
            ├── Rule 1 (Priority 0, highest)
            ├── Rule 2 (Priority 1)
            ├── Rule 3 ...
            └── Default Action (Allow or Block)
```

**WebACL evaluation:**
Rules are evaluated in priority order (0 = first evaluated, highest priority). The first rule that matches determines the action. If no rule matches, the default action applies.

**Scopes:**
- `CLOUDFRONT` — WebACL must be created in us-east-1, associated to CloudFront distribution
- `REGIONAL` — WebACL in the same region as ALB/API Gateway/AppSync/Cognito

---

## WebACL Creation

### Console

AWS Console → WAF & Shield → Web ACLs → Create web ACL

### Terraform

```hcl
resource "aws_wafv2_web_acl" "main" {
  name        = "my-app-waf"
  scope       = "REGIONAL"  # or "CLOUDFRONT"
  description = "WAF for My Application"

  default_action {
    allow {}  # Allow traffic not matching any rule
    # block {} # Alternatively, block by default (allowlist model)
  }

  # AWS Managed Rules - Common Rule Set
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 10

    override_action {
      none {}   # Use rule group's configured actions
      # count {} # Override to count (monitoring mode)
    }

    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesCommonRuleSet"

        # Override specific rules within the group
        rule_action_override {
          name          = "SizeRestrictions_BODY"
          action_to_use {
            count {}   # Monitor, don't block
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "AWSManagedRulesCommonRuleSet"
      sampled_requests_enabled   = true
    }
  }

  # Custom rate-based rule
  rule {
    name     = "LoginRateLimit"
    priority = 5

    action {
      block {}
    }

    statement {
      rate_based_statement {
        limit              = 300   # Requests per 5-minute window (100/min effective)
        aggregate_key_type = "IP"

        scope_down_statement {
          byte_match_statement {
            search_string         = "/api/auth/login"
            field_to_match {
              uri_path {}
            }
            text_transformation {
              priority = 0
              type     = "LOWERCASE"
            }
            positional_constraint = "STARTS_WITH"
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "LoginRateLimit"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "MyAppWAF"
    sampled_requests_enabled   = true
  }

  tags = {
    Environment = "production"
    Team        = "security"
  }
}

# Associate with ALB
resource "aws_wafv2_web_acl_association" "alb" {
  resource_arn = aws_lb.main.arn
  web_acl_arn  = aws_wafv2_web_acl.main.arn
}
```

---

## AWS Managed Rule Groups

AWS provides maintained rule groups covering common attack patterns.

### Free Managed Rule Groups (AWS)

| Rule Group | Protects Against | Size |
|---|---|---|
| `AWSManagedRulesCommonRuleSet` | OWASP Top 10, common exploits | 700 WCU |
| `AWSManagedRulesAdminProtectionRuleSet` | Admin interface exploitation | 100 WCU |
| `AWSManagedRulesKnownBadInputsRuleSet` | Log4SHELL, SSRF, malformed bodies | 200 WCU |
| `AWSManagedRulesSQLiRuleSet` | SQL injection (comprehensive) | 200 WCU |
| `AWSManagedRulesLinuxRuleSet` | Linux-specific OS attacks | 200 WCU |
| `AWSManagedRulesUnixRuleSet` | POSIX/Unix-specific attacks | 100 WCU |
| `AWSManagedRulesWindowsRuleSet` | Windows/PowerShell exploits | 200 WCU |
| `AWSManagedRulesPHPRuleSet` | PHP-specific vulnerabilities | 100 WCU |
| `AWSManagedRulesWordPressRuleSet` | WordPress-specific attacks | 100 WCU |
| `AWSManagedRulesAmazonIpReputationList` | AWS-detected malicious IPs | 25 WCU |
| `AWSManagedRulesAnonymousIpList` | Tor, VPNs, proxies | 50 WCU |

**WCU (Web ACL Capacity Units):** Each rule consumes WCU. WebACL default limit: 5,000 WCU.

### Paid Managed Rule Groups

**Bot Control** (additional charges):
- `AWSManagedRulesBotControlRuleSet`
- Classifies bots by type (search engine, scraper, tool, etc.)
- Common mode vs. Targeted mode (uses JavaScript fingerprinting, CAPTCHA)

**Fraud Control - ATP (Account Takeover Prevention)**:
- `AWSManagedRulesATPRuleSet`
- Detects credential stuffing on login pages
- Compares credentials against known-breached credential databases
- Requires JavaScript integration on the login page

**Fraud Control - ACFP (Account Creation Fraud Prevention)**:
- `AWSManagedRulesACFPRuleSet`
- Detects fraudulent account creation
- Identifies fake accounts, referral fraud

### Marketplace Managed Rule Groups

Third-party providers offer specialized rule groups:
- **Fortinet:** FortiWeb managed rules
- **F5:** F5 Rules for AWS WAF
- **Trend Micro:** Cloud One Application Security
- **Cyber Security Cloud:** WafCharm automatic tuning

---

## Rule Components

### Rule Statement Types

Statement types include byte match, geo match, IP set reference, regex pattern set reference, rate-based (with custom aggregation keys), and AND/OR/NOT compound statements. See `references/rule-statements.md` for full Terraform examples of each.

### Rule Actions

| Action | Behavior | Use |
|---|---|---|
| `allow` | Allow request to pass | Explicit allowlisting |
| `block` | Return 403 (or custom response) | Block attacks |
| `count` | Increment counter, allow request | Monitoring mode |
| `captcha` | Present CAPTCHA challenge | Suspected bots |
| `challenge` | Present JS challenge | Suspected bots (less friction) |

**Custom block response:**
```hcl
action {
  block {
    custom_response {
      response_code = 403
      custom_response_body_key = "block-response"
    }
  }
}

custom_response_body {
  key          = "block-response"
  content      = "{\"error\": \"Request blocked by security policy\"}"
  content_type = "APPLICATION_JSON"
}
```

---

## Bot Control

Bot Control classifies bot traffic into categories and allows action per category.

### Common Mode vs. Targeted Mode

| Mode | Detection Method | Cost |
|---|---|---|
| Common | Rule-based bot signatures | Lower |
| Targeted | JS fingerprinting + CAPTCHA + behavioral | Higher |

### Bot Control Rule Labels

AWS WAF Bot Control adds labels to requests for use in downstream rules:

```
awswaf:managed:aws:bot-control:bot:category:search_engine   # Googlebot, Bingbot
awswaf:managed:aws:bot-control:bot:category:content_fetcher # Generic crawlers
awswaf:managed:aws:bot-control:bot:category:http_library    # curl, wget, python-requests
awswaf:managed:aws:bot-control:bot:category:link_checker
awswaf:managed:aws:bot-control:bot:category:monitoring
awswaf:managed:aws:bot-control:bot:category:scraper
awswaf:managed:aws:bot-control:bot:category:seo             # SEO tools
awswaf:managed:aws:bot-control:signal:automated_browser     # Headless Chrome/Puppeteer
awswaf:managed:aws:bot-control:signal:non_browser_user_agent
awswaf:managed:aws:bot-control:targeted:signal:automated_browser
```

**Use labels in custom rules:**
```hcl
# Allow search engine bots, block scrapers
rule {
  name     = "AllowSearchEngines"
  priority = 100
  action {
    allow {}
  }
  statement {
    label_match_statement {
      scope = "LABEL"
      key   = "awswaf:managed:aws:bot-control:bot:category:search_engine"
    }
  }
}
```

---

## Logging and Monitoring

### Enable WAF Logging

```hcl
resource "aws_wafv2_web_acl_logging_configuration" "main" {
  log_destination_configs = [aws_kinesis_firehose_delivery_stream.waf_logs.arn]
  resource_arn            = aws_wafv2_web_acl.main.arn

  # Redact sensitive fields from logs
  redacted_fields {
    single_header {
      name = "authorization"
    }
  }
  redacted_fields {
    single_header {
      name = "cookie"
    }
  }
  
  # Log only requests that match rules (not all traffic)
  logging_filter {
    default_behavior = "DROP"  # DROP or KEEP
    filter {
      behavior    = "KEEP"
      condition {
        action_condition {
          action = "BLOCK"
        }
      }
      requirement = "MEETS_ANY"
    }
  }
}
```

**Log destinations:** Kinesis Firehose (→ S3/ES/Splunk), CloudWatch Logs, S3.

### CloudWatch Metrics

AWS WAF publishes metrics to CloudWatch per rule:

```
Namespace: AWS/WAFV2
Metrics:
  AllowedRequests        # Count of allowed requests
  BlockedRequests        # Count of blocked requests
  CountedRequests        # Count of counted (monitored) requests
  PassedRequests         # Count passed to next rule
  
Dimensions:
  WebACL: my-app-waf
  Region: us-east-1
  Rule: AWSManagedRulesCommonRuleSet
```

**CloudWatch Alarms:**
```hcl
resource "aws_cloudwatch_metric_alarm" "waf_blocks_high" {
  alarm_name          = "WAF-BlockedRequests-High"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "BlockedRequests"
  namespace           = "AWS/WAFV2"
  period              = "300"
  statistic           = "Sum"
  threshold           = "1000"
  alarm_description   = "WAF blocking high volume of requests"
  
  dimensions = {
    WebACL = aws_wafv2_web_acl.main.name
    Region = var.aws_region
    Rule   = "ALL"
  }
  
  alarm_actions = [aws_sns_topic.security_alerts.arn]
}
```

---

## Common Patterns

### Allowlist + Managed Rules

Ensure internal and monitoring IPs bypass WAF:

```hcl
# Priority 1: Allow trusted IPs first
rule {
  name     = "AllowTrustedIPs"
  priority = 1
  action { allow {} }
  statement {
    ip_set_reference_statement {
      arn = aws_wafv2_ip_set.trusted_ips.arn
    }
  }
}

# Priority 10: Managed rules (only applies if trusted IP rule didn't match)
rule {
  name     = "AWSManagedRulesCommonRuleSet"
  priority = 10
  override_action { none {} }
  statement {
    managed_rule_group_statement {
      vendor_name = "AWS"
      name        = "AWSManagedRulesCommonRuleSet"
    }
  }
}
```

### Gradual Deployment (Count → Block)

```hcl
# Step 1: Deploy in count mode (monitoring)
override_action { count {} }

# Step 2: After reviewing logs and tuning, change to:
override_action { none {} }  # Use rule group's default actions (block)
```

### Common Troubleshooting

**Rule blocking legitimate traffic:**
- Check WAF logs in CloudWatch or S3 for the terminating rule
- Identify which managed rule within the group triggered: check `terminatingRuleMatchDetails`
- Override the specific sub-rule to count mode within the managed rule group
- Create custom rule with higher priority (lower number) that allows the legitimate traffic pattern

**WAF not blocking known malicious traffic:**
- Verify WebACL is associated with the correct resource ARN
- Check rule priority order — earlier rules may be allowing traffic before later rules evaluate
- Verify scope matches resource type (CLOUDFRONT vs. REGIONAL)
- Check that default action is appropriate (Allow + specific block rules vs. Block + specific allow rules)

**High false positive rate on CommonRuleSet:**
- `SizeRestrictions_BODY` frequently false positives for file upload endpoints — override to count
- `GenericRFI_QueryStringArguments` can trigger on legitimate deep links — tune or exclude
- `CrossSiteScripting_BODY` can trigger on rich text content — exclude specific paths

## Reference Files

Load these for deep knowledge on specific topics:

- `references/rule-statements.md` — Full Terraform examples for each WAF rule statement type: byte match, geo match, IP set reference, regex pattern set reference, rate-based with custom keys, and AND/OR/NOT compound statements.

Files in this skill

  • SKILL.md13 KB
  • references/rule-statements.md2.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…