Quick answer
Web Cache Deception (Omer Gil, 2017) exploits the fact that CDNs cache by file extension (.css, .js, .png) regardless of the response's real Content-Type. The attacker requests /account/me.css → the app responds with the HTML of the victim's profile → CloudFront sees .css and caches it → an anonymous attacker requests the same URL → receives the cached private page. It works against default CloudFront + apps with permissive routing. Recurring bounties in Series B+ SaaS.
1. The concept as a mental image
[Víctima autenticada]
↓ GET /account/me.css
[App] → routing matchea /account/me → renderiza HTML privado con PII
↓ 200 OK, body = HTML del perfil
[CloudFront] → "ah, .css, cacheable" → guarda response en cache key (path)
↓ devuelve a víctima
[Atacante anónimo]
↓ GET /account/me.css
[CloudFront] → cache HIT → devuelve HTML privado SIN ir al origin
The flaw is the combination of two separately benign behaviors:
- The app does permissive routing:
/account/me.cssmatches/account/meand returns private HTML. - CloudFront caches by extension without validating
Content-Typeor cookies.
Neither piece is vulnerable on its own. Together → massive leak.
2. Prerequisites for it to work
| Component | Condition |
|---|---|
| App routing | /path/anything.css resolves to /path or /path/anything (catch-all, optional segments) |
| CloudFront cache rules | Caches *.css, *.js, *.png, *.jpg etc. by extension without checking cookies |
| App response | Returns 200 with a sensitive body (not a 301 redirect to /login) |
| Vary header | Missing Vary: Cookie or Cache-Control: private |
Condition #1 is what varies the most. Frameworks with a catch-all router (Express with *, Flask with path:, Rails with globbing routes, Next dynamic routes) are top candidates.
Keep reading the full chain
The remaining part includes the step-by-step PoC, exploitation code and the full chain that led to impact. Available to subscribers.
Practice this in a lab
Cloudfront Cache Deception
Keep learning · free account
Save your progress, unlock advanced payloads and rank your flags.
Related articles
Client-side admin bypass — boolean manipulation + BAC in a modern SPA
Real Quora report: SPA with an isAdmin boolean in localStorage that controls the UI + a backend that doesn't validate server-side. How to chain a boolean flip with BAC for admin takeover.
Cloudflare WAF — payload size bypass, oversized body, plan-specific limits
Bypassing the Cloudflare WAF by exploiting body size limits per plan (Free 100kb, Pro 100kb, Business 500kb, Enterprise 1mb): oversize payload trick + chunked transfer encoding.
Headless browsers — SSRF and RCE in endpoints that render URLs
Endpoints that accept URLs for screenshots/PDF (Puppeteer, Playwright, wkhtmltopdf) are an SSRF goldmine: cloud metadata, file://, gopher://, JS injection with XSS-to-RCE in the chromium sandbox.