WAF Configuration: 5 Mistakes That Leave You Exposed

December 15, 2025 | 11 min read | For DevOps & Security Engineers

A WAF you set and forget is a WAF that doesn't protect.

Web Application Firewalls are marketed as turnkey security solutions. Enable it, and you're protected. Reality is different. We've assessed organizations spending $50,000+/year on WAF services that were essentially running in "log only" mode - detecting attacks but blocking nothing.

This guide covers the five most common WAF misconfigurations we see, why they happen, and exactly how to fix them.

The WAF Illusion

WAFs fail not because the technology is bad, but because:

Let's fix each of these.

Mistake #1: Running in "Log Only" or "Simulate" Mode

The most common and most dangerous misconfiguration. Your WAF is watching attacks happen and writing them to a log file. It's not blocking anything.

Why it happens: Teams enable WAFs in detect-only mode "temporarily" during rollout to avoid breaking legitimate traffic. That temporary state becomes permanent.

The risk: Attackers face zero resistance. Your logs show attacks, but your application absorbs them all.

The Fix: Graduate to Block Mode with Staged Rollout

Don't flip from "log" to "block" overnight. Use a staged approach:

# Example: Cloudflare WAF staged rollout
# Week 1: Simulate mode, monitor logs
# Week 2: Block mode for high-confidence rules only
# Week 3: Block mode for medium-confidence rules
# Week 4: Block mode for all rules, with exceptions

# AWS WAF example - change from COUNT to BLOCK
{
  "Name": "SQLInjectionRule",
  "Priority": 1,
  "Action": {
    "Block": {}  # Changed from "Count": {}
  },
  "Statement": {
    "SqliMatchStatement": {
      "FieldToMatch": { "Body": {} },
      "TextTransformations": [
        { "Priority": 0, "Type": "URL_DECODE" }
      ]
    }
  }
}

Verification: After enabling block mode, check for increased 403 responses. If legitimate users complain, add targeted exceptions - don't revert to log mode.

Mistake #2: Overly Broad Bypass Rules

To stop false positives, someone added a bypass rule. That rule is now a highway for attackers.

Common examples:

The Fix: Narrow and Audit Bypass Rules

# BAD: Overly broad bypass
{
  "condition": "path starts with /api/",
  "action": "allow"  # Bypasses ALL WAF rules for API
}

# GOOD: Targeted exception for specific false positive
{
  "condition": "path equals /api/v1/upload AND method equals POST",
  "exception": ["rule-942100"],  # Only bypasses one specific rule
  "reason": "File uploads trigger SQLi false positive - JIRA-1234"
}

Audit checklist:

Mistake #3: No Rate Limiting (or Limits Set Too High)

WAF without rate limiting is like a bouncer who checks IDs but lets unlimited people through the door.

What we see:

The Fix: Multi-Layer Rate Limiting

# Cloudflare rate limiting example
# Layer 1: Global rate limit
rate_limit:
  path: "/*"
  threshold: 1000/minute
  action: challenge

# Layer 2: Sensitive endpoint limits
rate_limit:
  path: "/api/login"
  threshold: 5/minute
  action: block
  
rate_limit:
  path: "/api/search"
  threshold: 30/minute
  action: block

# Layer 3: Per-user limits (if authenticated)
rate_limit:
  path: "/api/*"
  key: "header:Authorization"
  threshold: 100/minute
  action: block

Setting the right threshold:

  1. Analyze normal traffic patterns for 2 weeks
  2. Find 99th percentile request rate per IP
  3. Set limit at 2-3x that value
  4. Monitor and adjust based on blocked requests

Mistake #4: Missing Request Body Inspection

Your WAF inspects URLs and headers. Attackers put payloads in POST bodies.

Why it happens:

The Fix: Enable Full Request Inspection

# AWS WAF - Enable body inspection with proper limits
{
  "SizeConstraintStatement": {
    "FieldToMatch": {
      "Body": {
        "OversizeHandling": "CONTINUE"  # Don't skip large bodies
      }
    },
    "ComparisonOperator": "LE",
    "Size": 65536,  # 64KB body inspection
    "TextTransformations": [
      { "Priority": 0, "Type": "NONE" }
    ]
  }
}

# ModSecurity - Enable request body access
SecRequestBodyAccess On
SecRequestBodyLimit 13107200      # 12.5MB limit
SecRequestBodyNoFilesLimit 131072 # 128KB for non-file content
SecRequestBodyLimitAction Reject

Performance Consideration

Body inspection adds latency. For high-traffic APIs, consider inspecting bodies only for sensitive endpoints, or use async inspection that doesn't block requests.

Mistake #5: Stale Rule Sets and No Custom Rules

Default OWASP rules are enabled. Nothing else. Rules haven't been updated since deployment.

Problems:

The Fix: Layer Custom Rules on Updated Defaults

# Custom rule examples

# Block requests with suspicious parameter patterns
{
  "name": "block-mass-assignment",
  "condition": "request.body contains 'isAdmin' OR 
                request.body contains 'role=' OR
                request.body contains 'permissions'",
  "action": "block",
  "endpoints": ["/api/users/*", "/api/profile"]
}

# Block known bad patterns specific to your stack
{
  "name": "block-graphql-introspection",
  "condition": "request.body contains '__schema' OR
                request.body contains '__type'",
  "action": "block",
  "endpoints": ["/graphql"]
}

# Rate limit password reset (business logic protection)
{
  "name": "rate-limit-password-reset",
  "condition": "path equals /api/password/reset",
  "rate_limit": "3 per hour per IP",
  "action": "block"
}

Rule update schedule:

Rule Type Update Frequency Source
OWASP Core Rules Monthly OWASP CRS GitHub
Vendor-managed rules Automatic Vendor updates
Custom rules After each pentest/incident Internal security team
IP reputation lists Daily Threat intelligence feeds

WAF Validation Checklist

Use this checklist to audit your WAF configuration:

Check Expected How to Verify
Mode is "Block" Yes Check WAF dashboard/config
Bypass rules documented All have JIRA/ticket refs Review exception list
Rate limits configured All endpoints have limits Test with load generator
Body inspection enabled Yes, with appropriate size Send POST with SQLi in body
Rules updated recently Within 30 days Check rule version/timestamp
Custom rules exist At least 5 app-specific rules Count custom rule entries
Logging captures full requests Headers, body, response code Review sample log entries
Alerts configured For high-severity blocks Trigger test attack, check alerts

Testing Your WAF

Don't assume your WAF works. Test it.

# Basic WAF testing (on your own systems only!)

# Test 1: SQLi detection
curl "https://yourdomain.com/search?q=1' OR '1'='1"
# Expected: 403 Forbidden

# Test 2: XSS detection
curl "https://yourdomain.com/page?name="
# Expected: 403 Forbidden

# Test 3: Path traversal
curl "https://yourdomain.com/file?path=../../../etc/passwd"
# Expected: 403 Forbidden

# Test 4: Rate limiting
for i in {1..100}; do curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain.com/api/endpoint; done | sort | uniq -c
# Expected: Mix of 200s initially, then 429s or 403s

# Test 5: POST body inspection
curl -X POST -d "username=admin' OR '1'='1" https://yourdomain.com/api/login
# Expected: 403 Forbidden

Automated WAF Testing

Tools like OWASP ZAP, Burp Suite, and Nuclei can automate WAF bypass testing. Run these against staging environments regularly.

Platform-Specific Quick Wins

Cloudflare

AWS WAF

Cloudfront + Shield

Akamai

When WAF Isn't Enough

WAFs are one layer. They don't replace:

Is Your WAF Actually Protecting You?

DDactic assesses WAF configurations and tests for bypasses. Find out if your investment is paying off.

Get a WAF Assessment
WAF Web Application Firewall Security Configuration DevOps OWASP Rate Limiting Cloudflare AWS WAF