Web Cache Poisoning & Deception
Sits between users & servers
Stores copies of web content (static or sometimes dynamic)
Uses "cache keys" to decide where to store and what to serve
Speeds up response, reduces server load
Attacker tricks the cache into storing a malicious response
When users visit the cached page, they get the attacker’s payload
Amplifies the reach of attacks like XSS, redirects, etc.
Exploits differences in cache and server URL handling
Attacker tricks the cache into storing someone else’s private data
Cache serves up sensitive info to anyone who requests the crafted URL
| Web Cache Poisoning | Web Cache Deception | |
|---|---|---|
| Goal | Inject malicious data | Expose private/sensitive data |
| Who’s Affected | Many users | Usually individual users |
| How | Manipulate cache keys | Exploit cache rule discrepancies |
| Impact | Mass distribution | Data leakage |
Find unkeyed input: Headers or parameters ignored by cache, but used by server
Inject payload: Craft request so server includes attacker’s content in response
Get it cached: Cache stores the poisoned response
Victims visit: All users get the attacker’s response until cache expires
Find dynamic endpoint: Returns private data (e.g., profile info)
Craft static-looking URL: Add .css, .js, or other static extension
Victim visits URL: Their sensitive response is cached
Attacker fetches: Requests the same URL, gets cached private data
Web Cache Poisoning
Web Cache Deception
Exclude unkeyed headers/params from responses
Sanitize anything that's reflected in the response
Make sure you are including all relevant headers/params in the cache key
Disable/limit caching on dynamic pages
Set Cache-Control: no-store, private on all dynamic or sensitive content
Review cache/CDN rules for static extensions, directories, or file names
Ensure cache and origin server treat URLs and delimiters the same way
Use CDN features like “Cache Deception Armor” (e.g. Cloudflare)