Web Cache Deception (WCD) is a security vulnerability that occurs when a web server or caching proxy misinterprets a client's request for a web resource and subsequently serves a different resource, which may often be more sensitive or private, after caching it.
- PortSwigger/param-miner
This extension identifies hidden, unlinked parameters. It's particularly useful for finding web cache poisoning vulnerabilities.
Example of Web Cache Deception:
Imagine an attacker lures a logged-in victim into accessing http://www.example.com/home.php/non-existent.css
- The victim's browser requests the resource
http://www.example.com/home.php/non-existent.css
- The requested resource is searched for in the cache server, but it's not found (resource not in cache).
- The request is then forwarded to the main server.
- The main server returns the content of
http://www.example.com/home.php
, most probably with HTTP caching headers that instruct not to cache this page. - The response passes through the cache server.
- The cache server identifies that the file has a CSS extension.
- Under the cache directory, the cache server creates a directory named home.php and caches the imposter "CSS" file (non-existent.css) inside it.
- When the attacker requests
http://www.example.com/home.php/non-existent.css
, the request is sent to the cache server, and the cache server returns the cached file with the victim's sensitivehome.php
data.
Example 1 - Web Cache Deception on PayPal Home Page
- Normal browsing, visit home :
https://www.example.com/myaccount/home/
- Open the malicious link :
https://www.example.com/myaccount/home/malicious.css
- The page is displayed as /home and the cache is saving the page
- Open a private tab with the previous URL :
https://www.example.com/myaccount/home/malicous.css
- The content of the cache is displayed
Video of the attack by Omer Gil - Web Cache Deception Attack in PayPal Home Page
Example 2 - Web Cache Deception on OpenAI
- Attacker crafts a dedicated .css path of the
/api/auth/session
endpoint. - Attacker distributes the link
- Victims visit the legitimate link.
- Response is cached.
- Attacker harvests JWT Credentials.
- Find an un-keyed input for a Cache Poisoning
Values: User-Agent Values: Cookie Header: X-Forwarded-Host Header: X-Host Header: X-Forwarded-Server Header: X-Forwarded-Scheme (header; also in combination with X-Forwarded-Host) Header: X-Original-URL (Symfony) Header: X-Rewrite-URL (Symfony)
- Cache poisoning attack - Example for
X-Forwarded-Host
un-keyed input (remember to use a buster to only cache this webpage instead of the main page of the website)GET /test?buster=123 HTTP/1.1 Host: target.com X-Forwarded-Host: test"><script>alert(1)</script> HTTP/1.1 200 OK Cache-Control: public, no-cache [..] <meta property="og:image" content="https://test"><script>alert(1)</script>">
The following URL format are a good starting point to check for "cache" feature.
- https://example.com/app/conversation/.js?test
- https://example.com/app/conversation/;.js
- https://example.com/home.php/non-existent.css
CloudFlare caches the resource when the Cache-Control
header is set to public
and max-age
is greater than 0.
- The Cloudflare CDN does not cache HTML by default
- Cloudflare only caches based on file extension and not by MIME type: cloudflare/default-cache-behavior
In Cloudflare CDN, one can implement a Cache Deception Armor
, it is not enabled by default.
When the Cache Deception Armor
is enabled, the rule will verify a URL's extension matches the returned Content-Type
.
CloudFlare has a list of default extensions that gets cached behind their Load Balancers.
7Z | CSV | GIF | MIDI | PNG | TIF | ZIP |
AVI | DOC | GZ | MKV | PPT | TIFF | ZST |
AVIF | DOCX | ICO | MP3 | PPTX | TTF | CSS |
APK | DMG | ISO | MP4 | PS | WEBM | FLAC |
BIN | EJS | JAR | OGG | RAR | WEBP | MID |
BMP | EOT | JPG | OTF | SVG | WOFF | PLS |
BZ2 | EPS | JPEG | SVGZ | WOFF2 | TAR | |
CLASS | EXE | JS | PICT | SWF | XLS | XLSX |
Exceptions and bypasses:
- If the returned Content-Type is application/octet-stream, the extension does not matter because that is typically a signal to instruct the browser to save the asset instead of to display it.
- Cloudflare allows .jpg to be served as image/webp or .gif as video/webm and other cases that we think are unlikely to be attacks.
- Bypassing Cache Deception Armor using .avif extension file - fixed
- Web Cache Deception Attack - Omer Gil
- Practical Web Cache Poisoning - James Kettle @albinowax
- Web Cache Entanglement: Novel Pathways to Poisoning - James Kettle @albinowax
- Web Cache Deception Attack leads to user info disclosure - Kunal pandey - Feb 25
- Web cache poisoning - Web Security Academy learning materials
- OpenAI Account Takeover - @naglinagli - Mar 24, 2023
- Shockwave Identifies Web Cache Deception and Account Takeover Vulnerability affecting OpenAI's ChatGPT - Gal Nagli
- Cache Deception Armor - Cloudflare
- How I Test For Web Cache Vulnerabilities + Tips And Tricks - bombon - Jul 21, 2022