What Is Web Cache Poisoning and How to Protect Against It?
Cache poisoning is when an attacker puts a malicious value into a request header the cache ignores, causing a tainted response to be cached. How it works, how to tell real poisoning apart from harmless SPA behavior, and how to prevent it.
Quick answer: Web cache poisoning is when an attacker sends a specially crafted request to a web server or a CDN (content delivery network) so that the server caches a malicious or personalized response that it should never have cached, and this poisoned response is then served to every innocent visitor who requests that same address afterward. The root of the problem is usually that the cache ignores certain request headers or parameters when deciding which requests count as the same; the attacker puts a malicious value into this ignored part, the server produces a different response, but the cache treats it as the same request because it never looked at that part, and stores it. This is a vulnerability class that can affect thousands of users with a single request, making it far broader in scope than a classic single user attack.
Instead of generating a page from scratch for every visitor, a website produces the response for a frequently requested page once and stores it for a while, serving later identical requests quickly from this stored copy, the cache. This is necessary for performance, but if the cache gets the decision of which requests actually count as the same wrong, it opens the door for an attacker to smuggle their own malicious request into the cache for an innocent address.
How poisoning happens
When a cache decides whether an incoming request matches a previously cached response, it usually considers only the URL path; it does not include certain special headers such as X-Forwarded-Host or X-Forwarded-Scheme, or certain query parameters, in this decision. However, the application server behind it may read this ignored header and place it into the response, for example into a redirect link or a script tag. When an attacker sends a request with their own controlled domain in the X-Forwarded-Host header, the application embeds this value into the page, and because the cache never looked at that header, it stores this tainted response as a normal one. From that moment on, every visitor requesting the same URL sees the poisoned page that redirects to the attacker's domain or runs their script.
| Step | What happens |
|---|---|
| Discovery | Which headers the cache ignores is identified |
| Injection | A request is sent with a malicious value in the ignored field |
| Storage | The tainted response produced by the server is stored in the cache |
| Spread | Every subsequent visitor to the same address sees the tainted response |
Why it is especially dangerous
A classic cross site scripting (XSS) flaw usually affects a single request or a single user; a successful cache poisoning, once it happens, affects everyone visiting that address until the cache expires or is manually cleared. This means an attacker can potentially serve malicious content, fake redirects or a credential theft page to thousands of users at once with a single request; conceptually it resembles HTTP request smuggling, because both stem from a mismatch in how a cache or an intermediary component interprets a request.
How it shows up in the real world
A cache poisoning finding can look harmless at first glance; for example, one might notice that a path with a static file extension, a font file, an image, is actually produced by a dynamic application and returns completely different content. But this alone is not proof of poisoning; many modern single page applications (SPA) are designed to return the same HTML shell for every non existent path, and this is a harmless behavior that can be confused with cache poisoning. The only way to prove a real poisoning is to place a unique marker (canary) in the field the cache ignores and, from a different client, request the same address again to confirm that this marker is actually being served from the cache.
How to prevent it
The foundation of defense is that the cache key used to cache a response must cover every input the application uses to generate that response; if the application reads a header, the cache must include that header in its key, or, in a safer approach, the application should never read untrusted headers at all. CDN and reverse proxy configurations should also be reviewed regularly, and which headers are included in the cache decision should be clearly documented; this should be treated as part of general WAF and web application firewall configuration.
The KAOS and DSET approach
DSET never treats a cache poisoning hypothesis as a confirmed finding based on a single observation; it proves it with canary based verification, confirming that the marked content is actually served from the cache to a different client. Our local AI engine KAOS does not immediately report suspicious cache behavior as high severity when it detects it; it first tests ignored headers, then uses canary injection to distinguish a real poisoning from normal application behavior, such as an SPA's catch all route handling. This discipline is the only reliable way to tell a false positive high severity finding apart from a real risk.
Frequently asked questions
Is every site that uses a CDN vulnerable to cache poisoning? No. The risk does not come from using a CDN but from a mismatch between what the cache considers and what the application actually uses. A well configured cache eliminates this risk by including every header and parameter the application reads in its own cache key.
If a site returns the same HTML on every request to a static path like .woff or .css, is this always a vulnerability? No, this alone is not proof. Many modern single page applications return the same shell HTML for every non existent path; this is normal behavior. Whether this is a real cache poisoning can only be determined by injecting a malicious value into an ignored input and verifying that it is actually served from the cache to a different client.
Is cache poisoning the same thing as cache deception? No, they are related but different. In cache poisoning, the attacker manipulates the response the server generates and this tainted response is served to everyone; in cache deception, the attacker causes another user's personalized, private response to be accidentally cached, and has that person's own information served back to themselves.
Sources
- OWASP Web Cache Poisoning: https://owasp.org
- PortSwigger Web Cache Poisoning Academy: https://portswigger.net
- DSET Cyber Security and Web Application Penetration Testing Services: https://dset.com.tr/hizmetler
To test whether your website or CDN configuration is vulnerable to cache poisoning with evidence based verification, contact DSET. We provide web security consulting from our Ankara Hacettepe Teknokent laboratory.
Kimliğinizi doğrulayın
Yetkilendirilmiş erişim alanı. Tüm giriş denemeleri kayıt altına alınır.