the_open_door
coffee
ESEN
← Back to index

Web Cache Poisoning

Web Cache Poisoning turns a malicious response into cached content served to other users. The cache (CDN, reverse proxy, Varnish) stores the response under a key built from a few request fields (usually method + host + path + query). If the app reflects a field that is not part of that key (an "unkeyed" header) into the response, we can poison the entry: the attacker sends the poisoned request once and the cache hands it to every victim who requests that same URL.

The flow is: (1) find a reflected unkeyed input, (2) put a payload in it, (3) get the response cached. Typical headers left out of the key:

GET /?cb=1 HTTP/1.1
Host: victim
X-Forwarded-Host: attacker.tld
X-Forwarded-Scheme: http

If the back-end uses X-Forwarded-Host to build an absolute URL (a <script src> or a link) and that response gets cached, every victim loads the resource from the attacker's host. To force caching you use your own cache buster (?cb=) while researching, then the real URL. Tooling: Param Miner (Burp) discovers unkeyed headers automatically.

Depending on what is reflected, impact ranges from a stored XSS served to everyone, to a mass redirect (open redirect) or resource theft. When the reflection comes through the Host header it overlaps with Host header injection.

How to detect it. In cache/CDN logs the signature is a cached response whose content depends on a request header that should not influence it (X-Forwarded-Host, X-Forwarded-Scheme, X-Host). A single path that starts serving content with foreign domains or paths, plus Age/X-Cache: HIT headers on anomalous responses, gives it away. Watch for repeated requests with odd X-Forwarded-* headers aimed at cacheable URLs.

Defence. Put every input that influences the response into the cache key (or stop reflecting untrusted headers), disable support for unused X-Forwarded-* headers, and mark request-dependent responses Cache-Control: no-store. Combines with request smuggling to force caching of arbitrary responses.