# Cache deception via path and extension tricks

Cache classifies URL by extension or prefix while origin serves authenticated dynamic content under it

_Area: Web infrastructure and server-side requests. Seen in 6 disclosed reports; 4 confirmed bounties, median $2,300, range $100-$6,500; latest 2025-06-04. Updated 2026-10-23._

## How it works
A cache decides whether a response is shareable using one view of the URL (its extension, a path prefix, or a normalized form), while the origin resolves that same URL to a different, authenticated resource. The cache stores a victim-specific response under a key an attacker can request anonymously. The broken assumption: "URLs that look static are safe to cache" and "cache and origin parse the URL the same way." Neither holds when parsers disagree on delimiters, encodings, or normalization [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-gotta-cache-em-all.md).

## Where it shows up
- Cache rules matching file extensions (.css, .js, .png, .jpeg) rather than actual Content-Type [E6](https://bugbountylibrary.com/r/h1%3A1698316.md)[E8](https://bugbountylibrary.com/r/h1%3A1271944.md)
- Path-prefix cache rules (e.g. /share/*) combined with encoded traversal (%2F, %2E%2E) the CDN does not decode [E2](https://bugbountylibrary.com/r/blog%3Anokline-github-io-bugbounty-2024-02-04-chatgpt-ato-html.md)
- Delimiter/normalization mismatches: semicolon, dot, %00, %0a, backslash vs forward slash, dot-segments [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-gotta-cache-em-all.md)[E4](https://bugbountylibrary.com/r/h1%3A1695604.md)
- Endpoints reflecting session cookies or CSRF tokens in 200 responses [E6](https://bugbountylibrary.com/r/h1%3A1698316.md)[E8](https://bugbountylibrary.com/r/h1%3A1271944.md)
- Authenticated 404/error pages embedding user context, cached by extension [E8](https://bugbountylibrary.com/r/h1%3A1271944.md)
- User-controlled path segments that can end in a file-like suffix [E7](https://bugbountylibrary.com/r/blog%3Amedium-freecodecamp-org-cache-deception-how-i-discovered-a-vulnerability-in-medium-and-helped-them-fix-it-31cec2a3938b.md)

## How to review
The invariant: for any URL an attacker can construct, the cache's cacheability decision and key must match the origin's resolution to the same resource, and no response containing session-specific data may be stored under a key reachable without that session. Check: does the cache classify by extension/prefix while the origin routes by decoded path? Does the origin return sensitive content on error paths? Are private responses marked Cache-Control: no-store? For each parser, compare a cache-hit response against the direct origin response (body and status) for the same URL to expose disagreements [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-gotta-cache-em-all.md).

## Variants seen
- Extension-based deception on authenticated pages reflecting session tokens [E6](https://bugbountylibrary.com/r/h1%3A1698316.md)
- Prefix-rule wildcard via encoded traversal [E2](https://bugbountylibrary.com/r/blog%3Anokline-github-io-bugbounty-2024-02-04-chatgpt-ato-html.md)
- Backslash normalization poisoning of asset keys [E4](https://bugbountylibrary.com/r/h1%3A1695604.md)
- Username-suffix static-file deception on profile pages [E7](https://bugbountylibrary.com/r/blog%3Amedium-freecodecamp-org-cache-deception-how-i-discovered-a-vulnerability-in-medium-and-helped-them-fix-it-31cec2a3938b.md)
- Authenticated 404 pages cached by .css suffix [E8](https://bugbountylibrary.com/r/h1%3A1271944.md)
- Adjacent, distinct scope: cache-key normalization collisions (decoded userinfo) [E3](https://bugbountylibrary.com/r/h1%3A824753.md) and JSONP callback-name keying of stale snapshots [E5](https://bugbountylibrary.com/r/h1%3A263760.md)

## Why fixes fail
Extension-only blocklists miss prefix rules and encoded traversal; fixing one delimiter leaves others [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-gotta-cache-em-all.md)[E2](https://bugbountylibrary.com/r/blog%3Anokline-github-io-bugbounty-2024-02-04-chatgpt-ato-html.md). The durable control is enforcing no-store on authenticated responses, not enumerating bad suffixes.

## Impact and severity
Leaked auth tokens, CSRF tokens, PII, and account takeover [E2](https://bugbountylibrary.com/r/blog%3Anokline-github-io-bugbounty-2024-02-04-chatgpt-ato-html.md)[E6](https://bugbountylibrary.com/r/h1%3A1698316.md)[E8](https://bugbountylibrary.com/r/h1%3A1271944.md); DoS via poisoned assets [E4](https://bugbountylibrary.com/r/h1%3A1695604.md). Worse when tokens enable full session hijack and when caches are shared across many users.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-gotta-cache-em-all.md
- E2: https://bugbountylibrary.com/r/blog%3Anokline-github-io-bugbounty-2024-02-04-chatgpt-ato-html.md
- E3: https://bugbountylibrary.com/r/h1%3A824753.md
- E4: https://bugbountylibrary.com/r/h1%3A1695604.md
- E5: https://bugbountylibrary.com/r/h1%3A263760.md
- E6: https://bugbountylibrary.com/r/h1%3A1698316.md
- E7: https://bugbountylibrary.com/r/blog%3Amedium-freecodecamp-org-cache-deception-how-i-discovered-a-vulnerability-in-medium-and-helped-them-fix-it-31cec2a3938b.md
- E8: https://bugbountylibrary.com/r/h1%3A1271944.md
