Web Cache Poisoning
Summary
Reports cluster around:
- backslash treated as forward-slash by cache layer, allowing 404 cache-poisoning DoS
- path-component traversal landing on attacker-controlled product (Amazon affiliate Linkpop)
- X-Forwarded-Host / X-HTTP-Method-Override poisoning of static assets
- cache-key not including critical params allowing targeted DoS. Most are CDN-specific edge cases.
Top Affected Components / Targets
Cloudflare / Akamai / Fastly-fronted sitesStatic-asset CDNsAny HTTP cache fronting an origin server
Common Attack Vectors
Probe path with backslash variants and observe whether origin and cache disagreeInject X-Forwarded-Host / X-HTTP-Method-Override / X-Original-URL into static-asset request and check cache poisoningUse cache-buster parameter to test without affecting other users
Common Payloads
GET /static/file.js with X-HTTP-Method-Override: HEADGET /asset\../poisoned (backslash normalize)GET /asset?dontpoisoneveryone=1 (cache-buster)GET / with X-Forwarded-Host: evil.com
Detection Strategy
For static assets, replay with X-HTTP-Method-Override / X-Forwarded-Host / X-Forwarded-Scheme using a cache-buster query param to avoid affecting other users; observe whether response varies and gets cached.
Probe /asset\.. and /asset/. and observe whether origin and cache disagree. Active testing must use unique cache-buster suffix to avoid actual DoS.
Tip: Testing tools that run these checks in parallel across every discovered endpoint can cut the time required substantially compared to fully manual testing, as long as they confirm findings with more than one signal to keep the false-positive rate down.
False-Positive Notes
Active testing must NEVER poison shared cache for real users - always use cache-buster suffix.
How to Test
Manual Testing Methodology
Here is a systematic approach to identifying Web Cache Poisoning vulnerabilities in a target application.
Before testing, map all input vectors that could be affected. Identify parameters, headers, cookies, and request bodies that interact with the vulnerable component. A proxy such as Burp Suite or OWASP ZAP, paired with normal browsing of the target, is usually enough to build this list.
Send a legitimate request and record the normal response: status code, content length, response time, and any identifying tokens. This baseline matters because it's what you'll compare later responses against once payloads are involved.
Inject test payloads into each identified input vector one at a time. Start with benign detection payloads before escalating to anything that could actually trigger the vulnerability. For Web Cache Poisoning specifically, send requests with a unique cache-buster in the query string, varying candidate unkeyed headers (X-Forwarded-Host, X-Forwarded-Scheme, X-Original-URL) one at a time, then request the same cache-buster URL again from a clean session to see if the manipulated response was cached and served back.
Compare the response against your baseline, looking specifically for whether a second, unmodified request for the same cache-buster URL returns the poisoned response — confirming the manipulation was actually cached and would be served to other visitors, not just reflected in the single crafted request.
Once a potential vulnerability is detected, confirm it with at least a few independent test cases to rule out coincidence. Document the exact request and response as proof. For Web Cache Poisoning, a confirmed finding typically means showing that attacker-controlled input changes the application's behavior in a way that matters for security, not just that a payload was reflected somewhere harmless.
Real-World Impact
Real-World Impact
Web cache poisoning tricks a caching layer into storing a malicious response and serving it to every subsequent visitor who requests the same cached URL, turning a single crafted request into an attack against every user who hits the cache afterward. The typical vector is an "unkeyed" input — a header or parameter the cache doesn't include in its cache key but the origin server's response still depends on — letting an attacker's manipulation of that input leak into a response cached for everyone else.
Once poisoned, the cached response can carry reflected XSS, an open redirect, or entirely attacker-controlled content to victims who never sent a malicious request themselves — from their perspective, they simply visited the legitimate site.
This makes cache poisoning a severity multiplier as much as a vulnerability of its own: a bug that would otherwise require an individual victim to click a crafted link becomes self-propagating to every cache-served visitor once poisoning succeeds.
Prevention & Remediation
Prevention and Secure Coding
Preventing Web Cache Poisoning takes a defense-in-depth approach — no single control below is sufficient alone, but together they close off both the primary path and the most common bypasses.
Include every response-affecting header in the cache key. Any header or parameter that changes the response body must be part of the cache key — or explicitly stripped/normalized before it can reach the origin server's response logic at all.
Normalize ambiguous headers before caching. Headers like Host, X-Forwarded-Host, and X-Forwarded-Scheme are common unkeyed-input vectors; validate and normalize them at the edge rather than letting the origin trust them blindly.
Conservative TTLs on anything reflecting user input. Keep cache lifetimes short for any endpoint whose response is influenced by user-controlled input, limiting the exposure window if poisoning does occur.
Test with cache-busting query strings during triage. When investigating a suspected poisoning vector, use a unique cache-buster to isolate whether a given header genuinely affects the cached response versus a false lead.
Source reports
A sample of the disclosed HackerOne reports this playbook was synthesized from.