AWS WAF Rate Limiting: Stop Layer 7 DDoS and Bot Attacks

Unprotected endpoints are magnets for Layer 7 DDoS attacks. When a botnet floods your application with thousands of HTTP requests, your backend server resources deplete rapidly, causing extreme latency or total downtime. Using AWS WAF rate limiting allows you to set a threshold for incoming requests, automatically blocking or challenging IP addresses that exceed your limits. This guide provides a technical walkthrough to implement these rules effectively, ensuring your application remains available for legitimate users while neutralizing malicious traffic.

One-sentence outcome: You will deploy a production-ready AWS WAF rate-based rule that identifies and mitigates high-volume traffic spikes before they reach your origin.

TL;DR — Create a Rate-based rule in AWS WAF with a 5-minute evaluation window. Set a threshold (minimum 100), choose "Block" or "CAPTCHA" as the action, and use "Scope-down statements" to target specific URI paths like /login or /api to prevent false positives.

Table of Contents

The Core Concept of Rate-Based Rules

💡 Analogy: Think of AWS WAF rate limiting as a bouncer at a club entrance. If a guest tries to enter the door 50 times in one minute, the bouncer marks them as suspicious and prevents them from entering for a set period. The bouncer doesn't care who the guest is; they only care about the frequency of the action.

AWS WAF (Web Application Firewall) tracks the number of requests coming from a specific IP address over a sliding 5-minute window. Unlike static rules that block IPs based on reputation or geography, rate-based rules are dynamic. They automatically "ban" an IP when it crosses a threshold and "unban" it once the request rate drops below that limit. This automation is essential for modern DevOps teams because it removes the need for manual IP blacklisting during an active attack.

As of the latest AWS WAF v2 updates, the minimum rate limit threshold is 100 requests per 5 minutes. You can aggregate these requests based on the source IP, or more advanced attributes like HTTP headers, cookies, or even custom keys if you use the "Advanced" configuration. This flexibility allows you to distinguish between a single user behind a NAT gateway and a distributed botnet.

When to Apply Rate Limiting

Not every endpoint needs the same level of protection. Applying a blanket rate limit of 100 across your entire site might accidentally block legitimate users who load many small assets (images, scripts) simultaneously. You should categorize your traffic into high-risk and low-risk zones to optimize your security posture.

1. Login and Authentication Endpoints: These are primary targets for brute-force and credential stuffing attacks. A strict rate limit here prevents bots from testing thousands of password combinations. If a normal user takes 10 seconds to type a password, an IP hitting /login 100 times in 5 minutes is almost certainly malicious.

2. Search and API Endpoints: Scraping bots often target search pages to steal proprietary data or pricing information. By implementing rate limiting on these specific URI paths, you can throttle scrapers without affecting the browsing experience of users on your homepage. This is particularly effective for e-commerce and real-time data platforms.

3. Heavy Computational Tasks: Some endpoints trigger expensive backend processes, such as PDF generation or complex database queries. Attackers use these to perform "Economic Denial of Sustainability" (EDoS) attacks, where they drive up your cloud bill rather than just crashing the site. Rate limiting ensures no single user can monopolize your CPU or memory resources.

How to Configure Rate Limiting Step-by-Step

Step 1: Create a Rate-Based Rule

Navigate to the AWS WAF Console and select your Web ACL. Click on "Rules" and then "Add rules" -> "Add my own rules and rule groups." Select "Rate-based rule" as the rule type. Give it a descriptive name like HighVolumeRequestBlocker.

Step 2: Define the Threshold and Evaluation Window

Choose your rate limit. For a general site-wide protector, 500–1,000 is a safe starting point. For sensitive endpoints, consider the minimum of 100. Ensure the "Evaluation window" is set to the default 5 minutes, as this is currently the standard for AWS WAF v2.

{
  "Name": "LimitRequestsPerIP",
  "Priority": 1,
  "Statement": {
    "RateBasedStatement": {
      "Limit": 100,
      "AggregateKeyType": "IP",
      "ScopeDownStatement": {
        "ByteMatchStatement": {
          "FieldToMatch": {
            "UriPath": {}
          },
          "PositionalConstraint": "STARTS_WITH",
          "SearchString": "/api/v1/",
          "TextTransformations": [
            {
              "Priority": 0,
              "Type": "NONE"
            }
          ]
        }
      }
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "LimitRequestsPerIP"
  }
}

Step 3: Implement CAPTCHA for "Gray" Traffic

Instead of a hard "Block" action, you can use "CAPTCHA." This is highly effective for bot mitigation. If a user exceeds the limit, they are prompted to solve a puzzle. If they pass, they receive a WAF token that allows them to continue. This prevents your rate limiting from becoming a "false positive" trap for power users or shared corporate IPs.

Common Pitfalls and Mitigation

⚠️ Common Mistake: Setting a threshold too low on the root domain (/). Modern web apps often load 50+ resources (JS, CSS, PNG) on the first hit. A threshold of 100 could block a legitimate user just for refreshing the page twice.

One major challenge is the Shared IP Problem. In many regions, large groups of users share a single outbound IP address through a NAT (Network Address Translation) gateway (e.g., a large office or a mobile carrier). If one person in that office triggers your rate limit, the entire office could be blocked from your site. To mitigate this, use "Forwarded IP" headers (like X-Forwarded-For) if your WAF is behind a proxy or CDN, but be wary of header spoofing.

Another pitfall is ignoring the "Scope-down statement." If you don't use a scope-down, your rule evaluates every single request to your entire domain. This increases the surface area for false positives. Always try to narrow your rate limiting to the specific paths or HTTP methods (like POST) that are actually being abused.

Finally, ensure you are not rate-limiting your own internal services. If you have automated health checks from Route 53 or internal monitoring tools hitting your API, you must add an IP allow-list exception to your rate-based rule to prevent your security policy from marking your own infrastructure as an attacker.

Verifying Rule Efficiency

After deploying your rule, you must verify it isn't blocking legitimate traffic. Use the AWS WAF Sampled Requests feature in the console. This shows you a real-time table of requests that were blocked, including the source IP, the URI path, and the specific rule that was triggered.

For long-term monitoring, enable AWS WAF logging to Amazon CloudWatch or S3. You can run CloudWatch Logs Insights queries to find the "Top Talkers"—IP addresses that are consistently hitting your limits. Run the following query to identify potential attackers:

fields @timestamp, httpRequest.clientIp, httpRequest.uri
| filter terminatingRuleId = "YourRateLimitRuleName"
| stats count(*) as requestCount by httpRequest.clientIp
| sort requestCount desc

If you see a single IP with thousands of blocked requests, your rule is working. If you see many different IPs with only 101 requests each, you may have set your threshold too low and are catching legitimate users in a "bursty" traffic pattern.

Metric-Backed Optimization Tips

Based on operational data from high-traffic AWS environments, here are three tips to improve your rate limiting strategy:

  • Use Custom Responses: When an IP is blocked, AWS WAF returns a 403 Forbidden by default. Change this to a 429 Too Many Requests. This is the standard HTTP status code for rate limiting and tells legitimate client-side scripts to back off and retry later, rather than assuming they are permanently banned.
  • Combine with IP Sets: If you identify persistent bad actors through your logs, move their IPs into a permanent "Blacklist" IP Set rule with a higher priority than your rate-based rule. This saves the WAF from having to evaluate the rate logic for known offenders.
  • Leverage Managed Rule Groups: AWS provides a "Bot Control" managed rule group. While this costs extra, it works alongside your manual rate limits to identify sophisticated bots that intentionally stay just below your 100-request threshold by rotating IPs.
📌 Key Takeaways
  • Minimum threshold is 100 requests per 5 minutes.
  • Use Scope-down statements to target sensitive URIs (/login, /api).
  • Prefer CAPTCHA over Block for interactive user paths to reduce false positives.
  • Monitor CloudWatch Metrics to tune thresholds based on real traffic patterns.

Frequently Asked Questions

Q. Does AWS WAF rate limiting protect against distributed DDoS (botnets)?

A. Yes, but with limitations. Since rate limiting is tracked per IP, it is highly effective against high-volume attacks from single sources. For highly distributed attacks (millions of IPs sending 1 request each), you should combine rate limiting with AWS Shield Advanced and Bot Control managed rules.

Q. What is the difference between a regular rule and a rate-based rule?

A. A regular rule is boolean; it checks if a condition (like an IP address or a string match) is true or false. A rate-based rule is stateful; it counts occurrences over a 5-minute window and changes its action (from Allow to Block) dynamically based on that count.

Q. How long does the block last after an IP exceeds the rate limit?

A. The block lasts as long as the request rate remains above the threshold. Once the IP's request count drops below your limit within the sliding 5-minute window, AWS WAF automatically removes the block, usually within a few minutes of the traffic subsiding.

For more detailed information on advanced security patterns, refer to the official AWS WAF Documentation.

Post a Comment