Skip to main content
2 min read Intermediate Web

Web Cache Poisoning

Web Cache Poisoning

AspectDetails
DescriptionWeb Cache Poisoning tricks a caching layer (CDN, reverse proxy, in-app cache) into storing a harmful response, which is then served to every user who requests the same cached key. Unlike Web Cache Deception (which leaks one victim's private page), poisoning weaponises a single request to attack all visitors, typically delivering stored XSS, redirects, or denial of service.
Conditions to be Vulnerable- A response is cached and the cache key ignores some input that still influences the response (an "unkeyed input").
- Unkeyed headers (e.g. X-Forwarded-Host, X-Forwarded-Scheme, X-Host) are reflected into the body, links, or redirects.
- The cache serves stale or shared responses across users.
Where to Find- Static-ish endpoints with caching (Cache-Control: public, Age, X-Cache: hit/miss).
- Responses that reflect headers like Host overrides, language, or cookies that are not part of the cache key.
- Cache key normalisation flaws (cache key flaws, fat GET, parameter cloaking).
Common Exploits- Reflect X-Forwarded-Host into a <script src> or canonical link to load attacker JS.
- Poison a redirect via X-Forwarded-Scheme: nothttps.
- DoS: send an oversized or malformed unkeyed header that makes the cached response an error page.
- Cache deception/key confusion via path delimiters.
ExampleRequest GET /en?cb=1 with X-Forwarded-Host: evil.com. If the app reflects it into <script src="//evil.com/a.js"> and the cache stores it keyed only on the path, every later visitor of /en?cb=1 runs attacker JavaScript.
How to Test1. Add a cache buster (unique query param) so you never poison real users.
2. Add candidate unkeyed headers (X-Forwarded-Host, X-Forwarded-For, X-Original-URL) and watch for reflection.
3. Confirm the response is cached (X-Cache: hit, Age increases) and that a clean request without your header returns the poisoned content.
ToolsBurp Suite with the Param Miner extension (header/parameter guessing, cache poisoning scan), Burp Repeater, curl for header injection and cache-header inspection.
Mitigation- Include every input that affects the response in the cache key, or do not reflect unkeyed inputs.
- Disable caching for dynamic/personalised responses (Cache-Control: no-store, private).
- Strip or reject untrusted forwarding headers at the edge.
- Normalise cache keys and avoid trusting client-supplied Host overrides.

Resources

CreditURL
PortSwigger Web Security Academyhttps://portswigger.net/web-security/web-cache-poisoning
PortSwigger (Practical Cache Poisoning research)https://portswigger.net/research/practical-web-cache-poisoning
OWASP: Cache Poisoninghttps://owasp.org/www-community/attacks/Cache_Poisoning