September 26, 2026
Web Cache Deception Part 1: How Caches Become Attack Surfaces
By // l1m1nal_3ntr0py

By // l1m1nal_3ntr0py
4 min read
Part 1 of 2 โ Part 2 covers advanced bypass techniques.
What Is a Web Cache?
A web cache sits between the user and the origin server. Its job is simple โ store responses for common requests and serve them directly without hitting the server again. Faster response times. Less server load. Better user experience.
Normal flow (no cache):
User โ Request โ Origin Server โ Response โ User
(every request hits the server)
Cached flow:
User โ Request โ Cache โ Response โ User
(cache serves stored response instantly)
(origin server never involved)Normal flow (no cache):
User โ Request โ Origin Server โ Response โ User
(every request hits the server)
Cached flow:
User โ Request โ Cache โ Response โ User
(cache serves stored response instantly)
(origin server never involved)Caches are shared infrastructure. One user's cached response can be served to another user entirely. That shared nature is exactly what makes cache deception possible.
Cache Keys โ How the Cache Decides What to Store
Not every request gets cached. The cache uses a cache key to identify requests โ typically the URL path and sometimes specific headers.
Cache key example:
GET /static/styles.css
Host: example.com
Cache stores this response and serves it to
ANYONE who requests /static/styles.cssCache key example:
GET /static/styles.css
Host: example.com
Cache stores this response and serves it to
ANYONE who requests /static/styles.cssThe critical insight: if the cache stores a response keyed to a URL, anyone who requests that URL gets the same cached response.
Detecting Cache Behaviour โ The X-Cache Header
Before exploiting anything โ confirm the cache exists and understand its state.
X-Cache: hit โ response served from cache
X-Cache: miss โ response served from origin server
X-Cache: dynamic โ response cannot be cached
X-Cache: refresh โ cache was outdated, refreshed from server
Cache-Control: public, max-age=3600
โ response is publicly cacheable for 1 hourX-Cache: hit โ response served from cache
X-Cache: miss โ response served from origin server
X-Cache: dynamic โ response cannot be cached
X-Cache: refresh โ cache was outdated, refreshed from server
Cache-Control: public, max-age=3600
โ response is publicly cacheable for 1 hourPractical detection in Burp:
Enable Param Miner โ Settings โ Add dynamic cachebuster. This adds a unique query string to every request so you can test caching behaviour without polluting the actual cache.
Send the same request twice:
- First response:
X-Cache: missโ went to origin - Second response:
X-Cache: hitโ served from cache โ caching confirmed!
Cache Rules โ What Gets Cached
Caches follow rules to decide what to store. Common rules:
File extensions:
.css .js .jpg .png .ico .woff โ static assets โ cached
Directory prefixes:
/static/ /assets/ /scripts/ โ cached
Specific filenames:
robots.txt favicon.ico index.html โ cached
Dynamic paths:
/profile /account /api/user โ NOT cached (usually)File extensions:
.css .js .jpg .png .ico .woff โ static assets โ cached
Directory prefixes:
/static/ /assets/ /scripts/ โ cached
Specific filenames:
robots.txt favicon.ico index.html โ cached
Dynamic paths:
/profile /account /api/user โ NOT cached (usually)The attack surface exists in the gap between what the cache thinks a request is, and what the origin server thinks it is.
Web Cache Deception โ The Core Concept
Web Cache Deception exploits discrepancies between how the cache interprets a URL and how the origin server interprets the same URL.
Attacker crafts a URL that:
โ Cache sees as: static file (cacheable!) โ
โ Origin server sees as: dynamic page (user data!) ๐
Result:
โ Origin server returns sensitive user data
โ Cache stores it (thinks it's a static file)
โ Anyone who requests that URL gets the cached data
โ Attacker requests the URL โ gets victim's data!Attacker crafts a URL that:
โ Cache sees as: static file (cacheable!) โ
โ Origin server sees as: dynamic page (user data!) ๐
Result:
โ Origin server returns sensitive user data
โ Cache stores it (thinks it's a static file)
โ Anyone who requests that URL gets the cached data
โ Attacker requests the URL โ gets victim's data!Attack 1 โ Exploiting Static Extension Cache Rules
The simplest form. Append a static file extension to a dynamic URL path.
Normal URL:
GET /api/user/profile
โ Cache: dynamic, skip โ
โ Origin: returns user profile data โ
GET /api/user/profile
โ Cache: dynamic, skip โ
โ Origin: returns user profile data โ
Manipulated URL:
GET /api/user/profile.js
โ Cache: .js extension = static file = CACHE IT! โ
โ Origin: ignores .js suffix, returns profile data โ
โ Cache stores profile data keyed to /api/user/profile.jsGET /api/user/profile.js
โ Cache: .js extension = static file = CACHE IT! โ
โ Origin: ignores .js suffix, returns profile data โ
โ Cache stores profile data keyed to /api/user/profile.jsAttack flow:
Step 1: Attacker crafts URL โ /api/user/profile.js
Step 2: Sends link to victim
Step 3: Victim clicks โ authenticated request hits cache
Step 4: Cache misses โ goes to origin โ returns profile data
Step 5: Cache stores victim's profile data!
Step 6: Attacker requests /api/user/profile.js
Step 7: Cache serves victim's profile data to attacker! ๐Step 1: Attacker crafts URL โ /api/user/profile.js
Step 2: Sends link to victim
Step 3: Victim clicks โ authenticated request hits cache
Step 4: Cache misses โ goes to origin โ returns profile data
Step 5: Cache stores victim's profile data!
Step 6: Attacker requests /api/user/profile.js
Step 7: Cache serves victim's profile data to attacker! ๐Why it works: The origin server uses routing to serve /api/user/profile โ the .js suffix doesn't match any route so it's ignored. The cache sees .js and applies its static extension rule.
Attack 2 โ Exploiting Path Mapping Discrepancies
Some servers use REST-style URLs where extra path segments are ignored.
REST-style URL handling:
Normal: /api/orders/123
Extra: /api/orders/123/foo
โ server ignores /foo โ returns order 123 anywayNormal: /api/orders/123
Extra: /api/orders/123/foo
โ server ignores /foo โ returns order 123 anywayThe exploit:
/api/orders/123/foo.css
โ Cache: .css = static file = CACHE IT! โ
โ Origin: /foo.css ignored โ returns order 123 data โ
โ Cache stores order data!/api/orders/123/foo.css
โ Cache: .css = static file = CACHE IT! โ
โ Origin: /foo.css ignored โ returns order 123 data โ
โ Cache stores order data!Even better with cache-specific extensions:
/api/orders/123/foo.ico
/api/orders/123/foo.woff
/api/orders/123/foo.exe/api/orders/123/foo.ico
/api/orders/123/foo.woff
/api/orders/123/foo.exeAny extension that triggers the cache rule works.
Detection tip: Use the Web Cache Deception Scanner BApp in Burp to automatically detect misconfigured web caches.
Exploiting Path Mapping โ Lab Example
Target URL: /my-account โ returns authenticated user data
Test 1: Does the origin ignore extra path segments?
GET /my-account/abc
โ Same response as /my-account? YES โ REST-style! โ
GET /my-account/abc
โ Same response as /my-account? YES โ REST-style! โ
Test 2: Does the cache store it?
GET /my-account/abc.js
โ First request: X-Cache: miss
โ Second request: X-Cache: hit โ CACHED! โ
GET /my-account/abc.js
โ First request: X-Cache: miss
โ Second request: X-Cache: hit โ CACHED! โ
Exploit:
Step 1: Trick victim into visiting /my-account/abc.js
Step 2: Victim's authenticated session loads their account data
Step 3: Cache stores it!
Step 4: Attacker visits /my-account/abc.js (unauthenticated)
Step 5: Gets victim's account data from cache! ๐Step 1: Trick victim into visiting /my-account/abc.js
Step 2: Victim's authenticated session loads their account data
Step 3: Cache stores it!
Step 4: Attacker visits /my-account/abc.js (unauthenticated)
Step 5: Gets victim's account data from cache! ๐How to Find Web Cache Deception Vulnerabilities
Step by step methodology:
Step 1 โ Confirm caching exists:
Send same request twice
Check X-Cache header
miss โ hit = cache confirmed โ
Send same request twice
Check X-Cache header
miss โ hit = cache confirmed โ
Step 2 โ Find dynamic endpoints with sensitive data:
/profile
/account
/api/user
/dashboard
/settings
Any endpoint returning user-specific data/profile
/account
/api/user
/dashboard
/settings
Any endpoint returning user-specific dataStep 3 โ Test static extension appending:
/profile.js
/profile.css
/profile.ico
/profile.png
Check if cached AND returns same data/profile.js
/profile.css
/profile.ico
/profile.png
Check if cached AND returns same dataStep 4 โ Test path segment appending:
/profile/test.js
/profile/abc.css
/api/user/123/test.ico/profile/test.js
/profile/abc.css
/api/user/123/test.icoStep 5 โ Verify the cache stored sensitive data:
Make first request authenticated
Make second request unauthenticated
If unauthenticated request returns sensitive data = VULNERABLE! ๐ฏMake first request authenticated
Make second request unauthenticated
If unauthenticated request returns sensitive data = VULNERABLE! ๐ฏImpact
What an attacker can steal via cache deception:
โ Session tokens and cookies
โ Personal information (name, email, address)
โ Financial data (account numbers, transactions)
โ API keys and authentication tokens
โ Private messages
โ Any data returned by dynamic authenticated endpointsWhat an attacker can steal via cache deception:
โ Session tokens and cookies
โ Personal information (name, email, address)
โ Financial data (account numbers, transactions)
โ API keys and authentication tokens
โ Private messages
โ Any data returned by dynamic authenticated endpointsThe severity depends entirely on what the cached endpoint returns. Account pages, API responses with tokens, and financial data make this Critical severity.
Summary
Web Cache Deception = tricking the cache into storing
dynamic authenticated content
Core technique:
โ Append static extension to dynamic URL
โ Cache stores it thinking it's static
โ Attacker retrieves cached sensitive data
Detection:
โ X-Cache header
โ Param Miner cachebuster
โ Web Cache Deception Scanner BApp
Attack types covered:
โ Static extension rules (.js .css .ico)
โ Path mapping discrepancies (REST-style URLs)Web Cache Deception = tricking the cache into storing
dynamic authenticated content
Core technique:
โ Append static extension to dynamic URL
โ Cache stores it thinking it's static
โ Attacker retrieves cached sensitive data
Detection:
โ X-Cache header
โ Param Miner cachebuster
โ Web Cache Deception Scanner BApp
Attack types covered:
โ Static extension rules (.js .css .ico)
โ Path mapping discrepancies (REST-style URLs)Part 2 coming โ Delimiter discrepancies, normalization attacks, encoded bypass techniques, and static directory exploitation.
Written by // l1m1nal_3ntr0py
- ๐ฆ @l1m1nal_3ntr0py
- ๐ github.com/l1m1nal-3ntr0py
- ๐ hackerone.com/nithig