Tests API rate limiting implementations for bypass vulnerabilities by manipulating request headers, IP addresses, HTTP methods, API versions, and encoding schemes to circumvent request throttling controls. The tester identifies rate limit headers, determines enforcement mechanisms, and attempts bypasses including X-Forwarded-For spoofing, parameter pollution, case variation, and endpoint path manipulation. Maps to OWASP API4:2023 Unrestricted Resource Consumption. Activates for requests involving rate limit bypass, API throttling evasion, brute force protection testing, or API abuse prevention assessment.
Instrucciones de origen · Vista previa de solo lectura
name
performing-api-rate-limiting-bypass
description
Tests API rate limiting implementations for bypass vulnerabilities by manipulating request headers, IP addresses, HTTP methods, API versions, and encoding schemes to circumvent request throttling controls. The tester identifies rate limit headers, determines enforcement mechanisms, and attempts bypasses including X-Forwarded-For spoofing, parameter pollution, case variation, and endpoint path manipulation. Maps to OWASP API4:2023 Unrestricted Resource Consumption. Activates for requests involving rate limit bypass, API throttling evasion, brute force protection testing, or API abuse prevention assessment.
Testing whether API rate limiting can be circumvented to enable brute force attacks on authentication endpoints
Assessing the effectiveness of API throttling controls against credential stuffing or account enumeration
Evaluating if rate limits are enforced consistently across all API versions, methods, and encoding formats
Testing if API gateway rate limiting can be bypassed through header manipulation or IP rotation
Validating that rate limits protect against resource exhaustion and denial-of-service conditions
Do not use without written authorization. Rate limit testing involves sending high volumes of requests that may impact service availability.
Most Often Missed & How to Confirm
IP-spoof header spray: rotate X-Forwarded-For, X-Real-IP, True-Client-IP, CF-Connecting-IP, and Forwarded - many gateways trust the first/last value blindly.
Counter-key drift: a trailing slash, case change, %-encoding, an extra query param (cache-buster), or an alternate API version often resets the counter.
Race conditions: fire N concurrent requests so the check-then-increment window lets a burst through before the counter updates.
Method/content-type switch: a limit on POST+json may not cover PUT/PATCH or form/multipart bodies.
Identity rotation: per-account limits fall to username casing, +tag, and whitespace variants.
How to confirm a hit (avoid false negatives): the bypass is real only when you exceed the baseline threshold and keep getting 200/401 instead of 429 (compare to the limit you measured first). Don't conclude negative until you've tried: every spoof header, path/case/encoding mutations, alternate versions, concurrency races, and both authenticated and unauthenticated limits separately.
Prerequisites
Written authorization specifying target endpoints and acceptable request volumes
Python 3.10+ with requests, aiohttp, and asyncio libraries
Burp Suite Professional with Turbo Intruder extension for high-speed testing
cURL for manual header manipulation testing
Knowledge of the target's CDN and WAF infrastructure (Cloudflare, AWS WAF, Akamai)
List of rate-limit bypass headers to test
Workflow
Step 1: Rate Limit Discovery and Baseline
Identify how rate limiting is implemented:
import requests
import time
BASE_URL = "https://target-api.example.com/api/v1"
headers = {"Authorization": "Bearer <token>", "Content-Type": "application/json"}
# Send requests and track rate limit headersdefprobe_rate_limit(endpoint, method="GET", count=100):
results = []
for i inrange(count):
resp = requests.request(method, f"{BASE_URL}{endpoint}", headers=headers)
rate_headers = {
"limit": resp.headers.get("X-RateLimit-Limit") or resp.headers.get("X-Rate-Limit-Limit"),
"remaining": resp.headers.get("X-RateLimit-Remaining") or resp.headers.get("X-Rate-Limit-Remaining"),
"reset": resp.headers.get("X-RateLimit-Reset") or resp.headers.get("X-Rate-Limit-Reset"),
"retry_after": resp.headers.get("Retry-After"),
"status": resp.status_code
}
results.append(rate_headers)
if resp.status_code == 429:
print(f"Rate limited at request {i+1}: {rate_headers}")
return results, i+1
time.sleep(0.05) # Small delay to avoid connection issuesprint(f"No rate limit triggered after {count} requests")
return results, count
# Test key endpoints
login_results, login_threshold = probe_rate_limit("/auth/login", "POST", 200)
api_results, api_threshold = probe_rate_limit("/users/me", "GET", 200)
search_results, search_threshold = probe_rate_limit("/search?q=test", "GET", 200)
print(f"\nRate Limit Summary:")
print(f" Login: Triggered at request {login_threshold}")
print(f" API: Triggered at request {api_threshold}")
print(f" Search: Triggered at request {search_threshold}")
Step 2: IP-Based Bypass Techniques
# Bypass Technique 1: Header-based IP spoofing
IP_SPOOFING_HEADERS = [
"X-Forwarded-For",
"X-Real-IP",
"X-Original-Forwarded-For",
"X-Originating-IP",
"X-Remote-IP",
"X-Remote-Addr",
"X-Client-IP",
"X-Host",
"X-Forwarded-Host",
"True-Client-IP",
"Cluster-Client-IP",
"X-ProxyUser-Ip",
"Forwarded",
"CF-Connecting-IP",
"Fastly-Client-IP",
"X-Azure-ClientIP",
"X-Akamai-Client-IP",
]
deftest_ip_spoofing_bypass(endpoint, method="POST", body=None):
"""Test if IP spoofing headers bypass rate limiting."""# First, trigger the rate limit normallyfor i inrange(200):
resp = requests.request(method, f"{BASE_URL}{endpoint}", headers=headers, json=body)
if resp.status_code == 429:
print(f"Rate limit triggered at request {i+1}")
break# Now test each spoofing header
bypasses_found = []
for header in IP_SPOOFING_HEADERS:
spoofed_headers = {**headers, header: f"10.0.{i%256}.{(i*7)%256}"}
resp = requests.request(method, f"{BASE_URL}{endpoint}", headers=spoofed_headers, json=body)
if resp.status_code != 429:
bypasses_found.append(header)
print(f"[BYPASS] {header} -> {resp.status_code}")
return bypasses_found
login_body = {"username": "test@example.com", "password": "wrongpassword"}
bypasses = test_ip_spoofing_bypass("/auth/login", "POST", login_body)
Controlling the number of requests a client can make to an API within a time window, typically enforced per IP, per user, or per API key
Unrestricted Resource Consumption
OWASP API4:2023 - APIs that do not properly limit the size or number of resources requested, enabling DoS or brute force attacks
X-Forwarded-For Spoofing
Manipulating the X-Forwarded-For header to make the server believe requests originate from different IP addresses, bypassing IP-based rate limits
Credential Stuffing
Automated injection of stolen username/password pairs against login endpoints, requiring rate limit bypass for large-scale attacks
Token Bucket
Rate limiting algorithm that allows bursts of requests up to a bucket size, refilling at a constant rate
Sliding Window
Rate limiting algorithm that tracks requests in a rolling time window, more resistant to burst attacks than fixed windows
Tools & Systems
Burp Suite Turbo Intruder: High-performance request sender for rate limit testing using Python-based scripting engine
ffuf: Fast web fuzzer capable of testing rate limits with configurable request rates and header manipulation
wfuzz: Web fuzzer with support for header injection, parameter fuzzing, and rate limit evasion techniques
Postman Collection Runner: Automated collection execution with variable rotation for rate limit bypass testing
Gatling/k6: Load testing tools that simulate realistic traffic patterns to test rate limiting under production-like conditions
Common Scenarios
Scenario: Login API Rate Limit Bypass Assessment
Context: A financial services API implements rate limiting on the login endpoint to prevent brute force attacks. The security team wants to verify the effectiveness of these controls before a compliance audit.
Approach:
Baseline: Send 100 requests to POST /api/v1/auth/login - rate limited at request 10 per minute per IP
Test X-Forwarded-For rotation: Send 100 requests with unique X-Forwarded-For values - rate limit bypassed (all requests return 401, not 429)
Test path variation: /api/v1/auth/login/ (trailing slash) resets the rate limit counter
Test API versioning: /api/v2/auth/login has no rate limiting configured (shadow API)
Test parameter pollution: Adding ?_=<random> to each request bypasses the rate limit
Test concurrent requests: 50 simultaneous requests from same IP - 45 succeed before rate limit kicks in (race condition in counter)
Determine that rate limiting is implemented at the nginx reverse proxy level using IP-only tracking, trusting X-Forwarded-For header without validation
Pitfalls:
Sending too many requests too fast and causing actual denial of service to the test environment
Not testing rate limits on password reset, MFA verification, and account enumeration endpoints
Assuming the rate limit applies globally when it may be per-endpoint or per-method only
Missing race conditions in rate limit counters that allow burst bypasses
Not testing both authenticated and unauthenticated rate limiting separately
Output Format
## Finding: Rate Limiting Bypass via X-Forwarded-For Header Spoofing
**ID**: API-RATE-001
**Severity**: High (CVSS 7.3)
**OWASP API**: API4:2023 - Unrestricted Resource Consumption
**Affected Endpoints**:
- POST /api/v1/auth/login
- POST /api/v1/auth/forgot-password
- POST /api/v1/auth/verify-mfa
**Description**:
The API rate limiting implementation relies on the X-Forwarded-For header
to identify client IP addresses. Since the application sits behind a load
balancer that does not strip or validate this header, an attacker can set
arbitrary X-Forwarded-For values to bypass the 10 requests/minute rate limit
on authentication endpoints.
**Bypass Methods Confirmed**:
1. X-Forwarded-For rotation: 1000 login attempts in 60 seconds (vs 10 limit)
2. Trailing slash path variation: /auth/login/ treated as separate endpoint
3. API v2 endpoint: No rate limiting configured
4. Race condition: 50 concurrent requests, 45 succeed before counter updates
**Impact**:
An attacker can perform unlimited brute force attacks against any user
account, bypassing the rate limit designed to prevent credential stuffing.
At 1000 attempts per minute, a 6-digit PIN can be brute-forced in under
17 minutes.
**Remediation**:
1. Configure the load balancer to set X-Forwarded-For and strip client-provided values
2. Implement rate limiting at the application layer using authenticated user ID, not just IP
3. Normalize URL paths before applying rate limit rules (strip trailing slashes, enforce lowercase)
4. Apply rate limits consistently across all API versions and content types
5. Use atomic rate limit counters (Redis INCR) to prevent race conditions
6. Implement progressive delays (exponential backoff) in addition to hard limits