Web cache deception tricks a cache into storing a private page, such as an account or order page, as if it were a static file. Anyone who then requests that URL may see the stored copy. Mark dynamic pages with no-store and private, and do not let CDN rules override them.
Definition
PortSwigger's Web Security Academy defines web cache deception as a vulnerability that lets an attacker trick a web cache into storing sensitive, dynamic content, caused by discrepancies between how the cache and the origin server handle requests. The attacker persuades a victim to visit a crafted URL, the victim's browser makes an ambiguous request for sensitive content, and the cache misreads it as a request for a static resource and stores the response. The attacker then requests the same URL.
The Academy distinguishes it from web cache poisoning. Poisoning injects content into a cached response. Deception stores private content for an attacker to read.
Why stores are exposed
Stores lean heavily on CDNs for speed, and cache rules often target static resources by file extension such as css or js. If the cache rule matches an extension in the URL while the origin ignores the extra path and returns the account page, the private response may be stored. Order history, addresses, partial card details and cart contents are all worth stealing.
What to check and fix
- Set Cache-Control no-store and private on every personalized response. MDN says to add private for user personalized content, especially responses after login and for cookie based sessions. If you forget it, the response can be stored in a shared cache and reused for multiple users.
- Configure CDN settings so caching rules do not override your Cache-Control headers. The Academy lists this as a prevention step.
- Turn on any protection your CDN offers against deception, such as a rule that checks the response content type matches the extension in the URL.
- Confirm the origin and the cache read URL paths the same way, including delimiters and normalization.
- Test after every CDN or routing change.
A quick manual test on your own store
While signed in to a test account on a staging site you own, request an account URL with an extra fake static looking segment appended. Then request it again from a signed out browser. If personal data appears, the page was cached. Use only test data and your own systems.
How it differs from a simple caching mistake
Forgetting private on a page is one error. Deception is the case where an attacker deliberately builds the URL that triggers storage. Both are fixed with the same headers, but deception also needs consistent path handling.
Quick check
Does no-store alone protect me?
It helps, but only if the CDN honors it. Confirm that no cache rule overrides your headers.
Does HTTPS prevent this?
No. The cache stores the decrypted response at its edge, so transport encryption does not stop it.
Sources
Safeguard offers DAST web app scanning, and the free scan at gold.safeguard.sh/scan is a starting point.
Last reviewed: 19 October 2026.