Apr 15, 2026 // aws

AWS WAF: What to Configure, What to Skip, and Why the Defaults Aren't Enough

AWS WAF protects web applications from common exploits, but the default managed rule groups leave gaps, and misconfigured rate limiting creates more problems than it solves. Here's a practical setup.

AWS WAF is on the compliance checklist for SOC 2, PCI DSS v4.0, and HIPAA-adjacent architectures — and for good reason. It provides a meaningful defense layer against OWASP Top 10 attacks at the edge, before traffic reaches your application.

But “enable WAF” isn’t enough. The AWS managed rule groups have false positive profiles that vary significantly by application type. Rate limiting requires careful baseline measurement before configuration. And some of the most commonly-enabled rule groups actively interfere with normal API traffic.

Here’s how to configure WAF that actually works.


What WAF does (and doesn’t do)

AWS WAF inspects HTTP/HTTPS requests before they reach your origin. You attach a web ACL to a resource — CloudFront distribution, ALB, API Gateway, AppSync, or Cognito user pool — and define rules that allow, block, or count requests matching specific conditions.

WAF does:

  • Block requests matching known attack patterns (SQL injection, XSS, path traversal)
  • Rate limit IPs or request attributes
  • Geo-restrict traffic to specific countries
  • Provide visibility into traffic patterns via CloudWatch and WAF logs

WAF does not:

  • Replace application-level input validation
  • Protect against authenticated application logic attacks (business logic flaws)
  • Inspect encrypted content that your application decrypts after receiving
  • Guarantee zero false positives — managed rules block legitimate traffic regularly if misconfigured

Pricing model

WAF pricing: $5/month per web ACL + $1/month per rule group + $0.60 per million requests inspected.

For a medium-traffic API processing 10 million requests/month with 3 rule groups: ~$17/month. Not expensive relative to what it protects, but rule group count multiplies the monthly base cost.

Managed rule groups from AWS are bundled into the $1/month/rule-group price. Third-party managed rule groups from the Marketplace (Cloudflare, Imperva, F5) have separate pricing.


The AWS managed rule groups: which to enable

AWS provides ~20 managed rule groups. Not all of them belong in every configuration. Here’s a practical subset:

Always enable:

AWS-AWSManagedRulesCommonRuleSet — Covers OWASP Top 10: SQL injection, XSS, size restrictions, path traversal. The baseline. Has a moderate false positive rate on APIs that use non-standard encoding or large payloads — monitor in Count mode first.

AWS-AWSManagedRulesAmazonIpReputationList — Blocks IPs associated with bots and scanners based on AWS threat intelligence. Low false positive rate for legitimate users. Good cost/benefit ratio.

AWS-AWSManagedRulesKnownBadInputsRuleSet — Blocks requests with patterns associated with Log4j/Log4Shell exploitation, Server-Side Request Forgery, and other known bad input patterns. Low false positive rate.

For APIs specifically:

AWS-AWSManagedRulesLinuxRuleSet — Linux-specific attack patterns (shell command injection, path traversal for Linux paths). Only relevant if your backend runs Linux and the attack surface includes file path operations.

AWS-AWSManagedRulesSQLiRuleSet — More aggressive SQL injection detection than the common rule set. High false positive rate for applications that legitimately include SQL-like strings in query parameters or request bodies (search functions, documentation APIs). Enable in Count mode first.

For older web applications:

AWS-AWSManagedRulesPHPRuleSet, AWS-AWSManagedRulesWordPressRuleSet — Only if you’re running PHP or WordPress. Irrelevant otherwise and adds cost.

What to skip (for most APIs):

AWS-AWSManagedRulesBotControlRuleSet — $10/month additional + per-request charges. Useful for protecting forms and human-interactive UIs from bot traffic. Frequently causes false positives for legitimate API clients with automated request patterns (monitoring, integrations). Evaluate carefully before enabling.


Start in Count mode, not Block mode

The single most important WAF configuration practice: enable new rule groups in Count mode first.

Count mode logs rule matches without blocking requests. After 48-72 hours, review the CloudWatch metrics and WAF logs to understand what’s being matched:

  • How many requests match each rule?
  • Are the matching requests legitimate traffic or actual attacks?
  • Which specific rules within the group are firing?

Only switch to Block mode after confirming the false positive rate is acceptable.

{
  "Name": "CommonRuleSet",
  "Priority": 10,
  "OverrideAction": {
    "Count": {}  // Start here
    // Switch to "None": {} to honor the group's block/count settings
  },
  "Statement": {
    "ManagedRuleGroupStatement": {
      "VendorName": "AWS",
      "Name": "AWSManagedRulesCommonRuleSet"
    }
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "CommonRuleSet"
  }
}

Rule exclusions for false positives

When a managed rule group blocks legitimate traffic, you have two options:

Option 1: Override specific rules to Count within the rule group.

{
  "ManagedRuleGroupStatement": {
    "VendorName": "AWS",
    "Name": "AWSManagedRulesCommonRuleSet",
    "RuleActionOverrides": [
      {
        "Name": "SizeRestrictions_BODY",
        "ActionToUse": {"Count": {}}
      }
    ]
  }
}

SizeRestrictions_BODY blocks request bodies over 8KB. If your API accepts large JSON payloads (file metadata, bulk operations), this rule fires on legitimate traffic. Override it to Count while keeping the rest of the rule group in Block mode.

Option 2: Allowlist specific request patterns before the managed rules run.

Create a high-priority rule (lower number = higher priority in WAF) that explicitly allows requests matching known-good patterns, before the managed rule groups can block them:

{
  "Name": "AllowLargeApiPayloads",
  "Priority": 1,
  "Action": {"Allow": {}},
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "ByteMatchStatement": {
            "SearchString": "/api/v1/bulk-upload",
            "FieldToMatch": {"UriPath": {}},
            "PositionalConstraint": "STARTS_WITH",
            "TextTransformations": [{"Priority": 0, "Type": "NONE"}]
          }
        }
      ]
    }
  }
}

Rate limiting

WAF rate limiting blocks IPs that exceed a request threshold within a 5-minute window.

The wrong way to configure rate limiting: Set a threshold without measuring baseline traffic first. 1,000 requests/5 minutes sounds reasonable but will block legitimate mobile clients with aggressive retry logic, monitoring tools that poll frequently, or API integrations under normal operation.

The right approach:

  1. Enable WAF with a rate limit rule in Count mode at a high threshold (e.g., 10,000 requests/5 minutes)
  2. Review CloudWatch’s RateLimitedRequests metric and WAF logs for 48 hours
  3. Find the 99th percentile request rate for legitimate IPs
  4. Set the block threshold at 2-3x the p99 rate
  5. Switch to Block mode

Rate limiting by IP vs. by request attribute:

IP-based rate limiting is the default. It breaks for:

  • Corporate NAT gateways where 200 employees share one IP
  • Mobile carriers with shared IPs
  • Load-balanced clients behind proxies

Rate limit by a request attribute instead when IP-based limits would have high false positive rates:

  • Header value (API key, JWT token identifier)
  • Custom header (X-Forwarded-For for the actual client IP behind proxies)
  • Query string parameter

WAF and PCI DSS v4.0

PCI DSS v4.0 Requirement 6.4 now mandates an “automated technical solution” to protect web applications from common attacks. AWS WAF satisfies this requirement.

For PCI compliance evidence, you need:

  • WAF enabled on all payment-related endpoints (at minimum)
  • Rules covering OWASP Top 10 (the Common Rule Set covers this)
  • Logging enabled (WAF logs to S3 or CloudWatch)
  • Regular review of WAF logs and false positive rates

WAF logs for PCI: enable full logging to S3, not sampled. QSAs may ask for log evidence of WAF operation over the assessment period. Sampled logs miss the completeness requirement.


Logging configuration

WAF logging goes to CloudWatch Logs, S3 (via Kinesis Data Firehose), or both.

For compliance: S3 via Kinesis Firehose. Configure the Firehose delivery stream to write to S3 with a lifecycle policy that retains logs for your compliance requirement (PCI: 12 months; SOC 2: typically 12 months; HIPAA: 6 years).

For operational monitoring: CloudWatch Logs with a short retention (7-14 days). Use CloudWatch Insights queries to investigate specific attack patterns or false positive incidents.

Filtering sensitive data from logs: WAF can redact specific header values from logs (Authorization, Cookie, X-API-Key) to prevent credential leakage into log storage. Configure field redaction on the logging configuration.


Cost optimization

WAF costs can grow with rule group count and request volume. Optimization levers:

Attach WAF at CloudFront, not ALB. CloudFront WAF inspection happens at the edge before traffic reaches your VPC. ALB WAF inspection happens after. CloudFront WAF blocks attack traffic before it consumes ALB capacity or EC2/ECS compute. For externally-facing applications, CloudFront WAF is almost always the right attachment point.

Terminate bots at CloudFront. If you’re getting significant bot traffic that’s blocked by WAF, the per-request WAF charge still applies even for blocked traffic. CloudFront’s built-in bot management (separate from WAF Bot Control) can handle simple bot signatures before WAF inspection.

Consolidate to a single web ACL. Each web ACL costs $5/month. Multiple applications sharing a single web ACL (possible when using CloudFront) reduces the base monthly cost.


Getting this right

WAF configuration is one of those things that’s easy to get wrong in ways that don’t show up immediately — false positives that affect a small percentage of legitimate traffic, logging that doesn’t cover the right endpoints, or rate limits that block monitoring tools during incident response. If you’re setting up WAF for a compliance requirement or want a review of an existing configuration, I’m available to help.


Nick Allevato is an AWS Certified Solutions Architect Professional with 20 years of infrastructure experience. He runs Cold Smoke Consulting, an independent AWS consulting practice.


← all writing