Description
Web Cache Deception is an attack technique discovered by security researcher Omer Gil in 2017. It exploits a discrepancy between how a cache server and an application server interpret the same URL. When these two components disagree about whether a URL represents a static or dynamic resource, an attacker can trick the cache into storing a sensitive, user-specific response and then retrieve that cached response without authentication.
CWE-444 — Inconsistent Interpretation of HTTP Requests captures the class of vulnerabilities arising from this kind of request smuggling and parsing ambiguity. Under A05:2021 — Security Misconfiguration, the flaw stems from cache servers and application servers being deployed without coordinating their URL parsing and caching rules — each making locally reasonable decisions that are collectively insecure.
The attack is particularly impactful because it is passive in execution: the attacker crafts a URL and sends it to a victim (via phishing or an embedded link). When the victim visits it, their browser receives their authenticated response — which the cache simultaneously stores. The attacker then retrieves the cached version without authentication.
How It Works
Consider a banking application where https://bank.example.com/account/settings serves personalised account information with Cache-Control: no-store.
The attacker crafts the URL:
https://bank.example.com/account/settings/nonexistent.css
When the victim visits this URL:
-
The application server receives the request, ignores the
.csssuffix (it does not map to anything), and processes it as a request to/account/settings— returning the victim's authenticated account page with personal data. -
The cache server (CDN, Varnish, Nginx) sees a URL ending in
.cssand classifies it as a static resource eligible for caching. It stores the response using the full URL as the cache key. -
The attacker then requests
https://bank.example.com/account/settings/nonexistent.csswithout any authentication cookies — and receives the victim's cached account page.
The attack works because the cache uses URL extension to determine cacheability while the application uses URL routing (which ignores the .css suffix). This is the path traversal variant of CWE-444.
A second variant exploits path delimiter inconsistencies. If the cache treats the URL as /account/settings/nonexistent.css (full path) but the application normalises it to /account/settings, the same discrepancy arises.
# Attacker-crafted URL for a victim to visit:
GET /dashboard/profile;.js HTTP/1.1
Host: app.example.com
# Application interprets as: /dashboard/profile (semicolon is a path parameter delimiter)
# Cache interprets as: static .js file → stores response
Impact
- Sensitive data exposure — cached pages can contain account details, payment information, session identifiers, PII, and private messages belonging to the victim.
- Session token theft — if the application includes session cookies or tokens in the page body or headers that are cached, an attacker can use them to fully impersonate the victim.
- Credential harvesting at scale — a phishing campaign delivering web cache deception links to many users can accumulate multiple victims' cached personal pages simultaneously.
- Compliance violation — caching user-specific pages containing PII violates GDPR's data minimisation and access control requirements.
Detection
- Append static resource extensions to authenticated endpoint URLs — test
<authenticated_url>/test.css,<authenticated_url>/test.js, and<authenticated_url>/test.pngand compare the response to the canonical URL. - Check cache headers in the modified URL response — look for
X-Cache: HIT,Age:(non-zero), orCF-Cache-Status: HITheaders indicating the response was cached. - Replay the modified URL without authentication cookies — if the unauthenticated request returns the authenticated response, the finding is confirmed.
- Test path delimiter variants — try
;,.,%23(#), and%3f(?) as separators between the legitimate path and the appended static suffix. - Review cache server rules — inspect Nginx, Varnish, or CDN configuration for rules that cache based on file extension without checking
Cache-Controlresponse headers.
Remediation
Configure the cache to respect Cache-Control headers. The application must send Cache-Control: no-store, no-cache on all authenticated responses, and the cache server must be configured to honour these directives unconditionally — never overriding them based on URL extension.
Align URL interpretation between cache and application. Configure the cache to normalise URLs consistently with the application: if the application strips path parameters after semicolons, the cache key should use the same normalised URL.
Use user-specific cache keys or disable caching for authenticated paths. Configure the CDN or reverse proxy to never cache responses for paths under /account/, /dashboard/, /api/user/, or any other authenticated prefix.
Validate extension-based caching rules. Audit all cache location blocks or CDN page rules that use file extension matching. Ensure they include an additional condition requiring the absence of authentication cookies before caching.
