Cloud Security Wire
AWS Azure GCP RSS
AWS Hardening Guide high

AWS WAF Misconfigurations and Bypass Techniques: Hardening Guide

AWS WAF protects fewer applications than most AWS teams believe. Default configurations leave significant coverage gaps: rules in Count mode, missing API Gateway attachments, inspection limits on large bodies, and bypass-friendly regex patterns. This guide covers the gaps and how to close them.

By Cloud Security Wire · ·
#aws#waf#web-acl#rate-limiting#bypass#api-gateway#cloudfront#alb#managed-rules#sql-injection#xss#hardening#2026
High Severity

This issue has been assessed as high severity. Review affected configurations immediately.

AWS WAF is frequently configured but infrequently hardened. The typical deployment path — attach a Web ACL to an Application Load Balancer, enable the AWS Managed Core Rule Set — creates a sense of protection that doesn’t match the actual coverage. Rules default to Count mode during rollout and often stay there. API Gateway stages outside the “main” load balancer path get missed. The 8 KB body inspection limit leaves large uploads uninspected. And several well-documented techniques can bypass pattern-matching rules without triggering managed rule groups.

This guide covers the real misconfiguration landscape and the specific controls that address it.

The Count Mode Problem

AWS WAF rules operate in either Block or Count mode. Count logs a match without taking action. The intended use is evaluation: run new rules in Count for a week, review the logs, confirm there are no false positives, then switch to Block.

In practice, Count mode becomes permanent. Teams roll rules out under pressure, see counts in logs, assume someone will review them, and move on. Months later the WAF has 15 rules in Count mode and is blocking nothing for the matched traffic.

Audit your Web ACLs:

# List all WAF Web ACLs in a region
aws wafv2 list-web-acls --scope REGIONAL --region eu-west-1

# Get the full configuration of a specific ACL
aws wafv2 get-web-acl \
  --name MyWebACL \
  --id <acl-id> \
  --scope REGIONAL \
  --region eu-west-1 \
  --query 'WebACL.Rules[?OverrideAction].{Name:Name,Action:OverrideAction}' \
  --output table

The OverrideAction field controls whether a managed rule group is overridden to Count. Any managed rule group with "Count": {} in its override is not blocking.

Fix — switch managed rule groups to block mode:

# Use update-web-acl to remove override actions
# First get current lock token
TOKEN=$(aws wafv2 get-web-acl \
  --name MyWebACL --id <acl-id> \
  --scope REGIONAL --region eu-west-1 \
  --query 'LockToken' --output text)

# Update rule — remove OverrideAction (leaving it block by default)
# Pass the full updated rules array, removing OverrideAction from managed groups

Missing Coverage: API Gateway and AppSync

WAF can protect ALB, CloudFront, API Gateway (REST APIs), AppSync GraphQL APIs, and Cognito User Pools. The coverage gap is almost always on non-ALB resources.

Check what’s actually protected:

# List all Web ACL associations
aws wafv2 list-resources-for-web-acl \
  --web-acl-arn arn:aws:wafv2:eu-west-1:123456789012:regional/webacl/MyWebACL/<id>

# Find API Gateway stages with no WAF
aws apigateway get-rest-apis --query 'items[].id' --output text | \
  xargs -I {} aws apigateway get-stages --rest-api-id {} \
    --query 'item[?!webAclArn].{API:restApiId,Stage:stageName}' --output table

Any REST API stage without a webAclArn is unprotected. The same check applies to AppSync APIs:

aws appsync list-graphql-apis --query 'graphqlApis[?!wafWebAclArn].[name,apiId]' --output table

The 8 KB Body Inspection Limit

By default, AWS WAF only inspects the first 8 KB of a request body. For requests larger than 8 KB, the remainder is forwarded to your application uninspected.

This affects SQL injection and XSS rules on upload endpoints. An attacker can pad a malicious payload past the 8 KB mark to bypass inspection:

POST /upload HTTP/1.1
Content-Type: application/json
Content-Length: 12000

{"padding": "AAAAAAA...AAAAAAA",  <-- 8,001 bytes of padding
 "query": "'; DROP TABLE users; --"}

Fix — increase the body inspection size limit:

# In your Web ACL configuration, set body oversize handling
# Use the console or CloudFormation to set RequestBodyAssociatedResourceTypeConfig
# Options: 8KB (default), 16KB, 32KB, 64KB
# Cost: additional WCU consumption for larger sizes

In CloudFormation:

AssociationConfig:
  RequestBody:
    - AssociatedResourceType: APPLICATION_LOAD_BALANCER
      DefaultSizeInspectionLimit: KB_64

Bypass Techniques and Managed Rule Gaps

URL Encoding and Double Encoding

AWS Managed Rules decode URL encoding before matching. But double-encoding can bypass some rules:

# Single-encoded — caught
/admin?q=%27+OR+1%3D1--

# Double-encoded — may bypass
/admin?q=%2527+OR+1%253D1--

Test your WAF against double-encoding before assuming SQLiRuleSet covers it.

JSON Body Encoding

The AWS Managed Core Rule Set inspects request bodies as raw text. When an application expects JSON and the WAF pattern matching treats the body as text, JSON structure can be used to fragment injection payloads:

{"username": "ad", "suffix": "min' OR '1'='1"}

The SQLiMatchStatement in WAF supports a JsonBody transformation that applies JSON-aware parsing before matching. Enable it explicitly for JSON APIs.

Large File Upload Bypass

Upload endpoints that accept multipart form data with large files effectively have no WAF coverage beyond the first 8 KB of the body. If your application has upload functionality, configure separate WAF rules with size constraint statements to block oversized uploads at the WAF layer, before the body reaches your application.

Rate-Based Rule Threshold Calibration

Default rate-based rule examples use 2,000 requests per 5 minutes as the threshold. For most production applications, legitimate users don’t approach 2,000 requests in 5 minutes. The effective protection starts at the baseline traffic level for your specific application.

Calibrate rate limits from actual traffic:

# Get WAF sampled requests to understand legitimate request rates
aws wafv2 get-sampled-requests \
  --web-acl-arn <arn> \
  --rule-metric-name AllowedRequests \
  --scope REGIONAL \
  --time-window StartTime=$(date -d '1 hour ago' +%s),EndTime=$(date +%s) \
  --max-items 500

Set rate-based rules conservatively — 100 to 500 requests per 5-minute window per IP for login endpoints; tighter for password reset and account creation paths.

WAF Logging: What’s Missing Without It

WAF logging is not enabled by default. Without it, you have no visibility into what the WAF is inspecting, what it’s counting, and what traffic is reaching your application.

Enable logging to CloudWatch Logs or S3:

aws wafv2 put-logging-configuration \
  --logging-configuration '{
    "ResourceArn": "arn:aws:wafv2:eu-west-1:123456789012:regional/webacl/MyWebACL/<id>",
    "LogDestinationConfigs": [
      "arn:aws:logs:eu-west-1:123456789012:log-group:aws-waf-logs-production"
    ],
    "LoggingFilter": {
      "DefaultBehavior": "KEEP",
      "Filters": [
        {
          "Behavior": "KEEP",
          "Requirement": "MEETS_ANY",
          "Conditions": [{"ActionCondition": {"Action": "BLOCK"}}]
        }
      ]
    }
  }'

Logging blocked requests at minimum. A CloudWatch Metric Filter on blocked requests and an alarm at > 100 blocks per minute provides a low-noise signal for active attack traffic.

Priority Hardening Checklist

  1. Audit Count mode: Every managed rule group override should have a documented reason. Remove OverrideAction from groups that have passed evaluation.
  2. Check coverage: Inventory all API Gateway stages, AppSync APIs, and Cognito User Pools against the list of Web ACL associations.
  3. Raise body inspection limit: Set to 64 KB for applications handling significant POST bodies. Cost impact is manageable at most traffic volumes.
  4. Enable WAF logging: Block-event logging at minimum, full logging for high-risk endpoints.
  5. Tighten rate-based rules: Calibrate per endpoint against actual traffic baselines. Login endpoints should have the tightest limits.
  6. Add AWSManagedRulesKnownBadInputsRuleSet: This managed rule group, often omitted, blocks log4j patterns, Spring4Shell, and similar mass-exploitation probes.
  7. Enable AWS Managed Rules Bot Control for scraping-sensitive paths (pricing pages, product inventory, search).

WAF is a detection and filtering layer, not a complete application security control. Hardened WAF configuration alongside application-layer input validation is the correct model — WAF reduces the attack surface that reaches code you control.

← All Analysis Subscribe via RSS