What is web cache deception?
Web cache deception is an attack class where an attacker manipulates URL path and extension to trick a CDN or reverse-proxy cache into storing an authenticated response as a cacheable resource. The next request to that URL from any user — including unauthenticated users or attackers — returns the cached authenticated content. Discovered by Omer Gil in 2017 and still one of the most consistently exploitable misconfigurations in CDN-fronted applications in 2026.
The exploitation pattern
The pattern depends on a mismatch between how the application routes URLs and how the CDN caches them. Many CDNs are configured to cache any URL ending in a static-file extension (.css, .js, .png, .svg, .jpg). The application framework typically ignores extra path components after a valid route — so /profile and /profile/foo.css both resolve to the same authenticated profile endpoint. The CDN sees the .css extension and caches the response.
The attack: an authenticated victim visits an attacker-crafted link /profile/attacker.css. The application returns the victim's profile data; the CDN caches it under the .css URL. The attacker then requests the same URL unauthenticated and receives the cached victim profile — including API tokens, session cookies, PII, or whatever the authenticated endpoint returned.
Detection commands
The detection sequence has three steps. First, identify the cache. Second, construct a candidate deception URL. Third, verify caching behaviour.
# Step 1: Identify cache via response headers
curl -I https://target.example/profile \
-H "Cookie: session=<valid-session>"
# Look for: X-Cache, CF-Cache-Status, Age, Via, X-Varnish
# Step 2: Attempt deception with static extension
curl -I "https://target.example/profile/x.css" \
-H "Cookie: session=<valid-session>"
# Expect: 200 with authenticated content body + Cache-Control: public
# Step 3: Verify cache from unauthenticated session
curl "https://target.example/profile/x.css"
# If this returns the previously-cached authenticated response — deception confirmedCommon cache triggers to test
/profile/x.cssand/profile/x.js— classic extension bypass/profile.css— path-level extension injection/profile;x.css,/profile?x.css— delimiter bypass/profile/x.svg,/profile/x.gif— alternative static extensions- Path-segment injection:
/static/../profile - Encoded dot:
/profile%2Ecss
Defensive configuration
Three defensive patterns reliably eliminate web cache deception. First, strict path matching: configure the application framework to reject requests where the URL contains extra path components after a valid route. Explicit routing with 404 on unmatched suffix defeats the deception at the application layer.
Second, Cache-Control enforcement: authenticated endpoints should always return Cache-Control: no-store, private — CDNs honour this header and will not cache the response even if the URL suggests a static extension. Framework-level middleware that forces this header on authenticated endpoints is the simplest and most robust defence.
Third, CDN configuration: configure the CDN to only cache URLs that explicitly match static asset paths (/static/*, /assets/*) rather than inferring cacheability from file extension. Cloudflare, Fastly, Akamai, and CloudFront all support path-based caching rules that eliminate the extension-based inference.
Related attacks
Web cache deception sits alongside cache poisoning (attacker gets malicious content into the cache that affects victim users) and cache key fixation (attacker manipulates the cache key to force a specific cache entry). All three exploit the mismatch between application routing and cache behaviour; the defensive patterns above address all three when applied together.