What is Web Cache Deception? Ways to Exploit, Examples and Impact
Learn how Web Cache Deception (WCD) works, view practical exploit examples, and discover how to prevent sensitive data leaks in your web application.
Web Cache Deception (WCD) is a sophisticated web security vulnerability that allows an attacker to trick a caching server into storing sensitive, private information and making it publicly accessible. Unlike many traditional web attacks that target the database or the client-side browser directly, WCD exploits the architectural discrepancy between how a web server and a cache (like a CDN or reverse proxy) interpret incoming requests. In this guide, we will break down the mechanics of Web Cache Deception, explore how it is exploited with practical examples, and discuss how you can protect your infrastructure.
Understanding the Basics of Web Caching
Before diving into the vulnerability, it is essential to understand the role of a cache. In modern web architecture, performance is king. To speed up page load times and reduce the load on the origin server, organizations use caching layers. These are often Content Delivery Networks (CDNs) like Cloudflare or Akamai, or reverse proxies like Nginx or Varnish.
Caches store copies of "static" files—things that don't change from user to user, such as images (.jpg), stylesheets (.css), and scripts (.js). When a user requests a static file, the cache serves it directly. However, for "dynamic" content—like a user's profile page or a bank statement—the cache should ideally ignore the request and let it pass through to the origin server, which generates a unique response for that specific user.
Web Cache Deception occurs when an attacker manipulates a URL so that the cache mistakenly believes a dynamic, private response is actually a static, public file.
How Web Cache Deception Works
The root cause of WCD is a disagreement between the cache and the origin server regarding which part of a URL is the "real" path and which part is just extra information. This is often referred to as "Path Confusion."
The Anatomy of an Attack
Imagine a web application where a user's private dashboard is located at https://example.com/api/user/profile. This page returns sensitive data like email addresses and API keys.
- The Attacker's Craft: The attacker crafts a malicious URL by appending a fake static file extension to the end of the legitimate path:
https://example.com/api/user/profile/test.css. - The Cache Interpretation: When the request hits the cache (the CDN), the cache looks at the end of the URL. It sees
.cssand thinks, "This is a stylesheet. Stylesheets are static and should be cached for everyone." - The Origin Interpretation: The cache forwards the request to the origin server. The origin server, however, might be configured to ignore the trailing
/test.csspart (a behavior common in frameworks like Django or Spring). It treats the request as a call tohttps://example.com/api/user/profile. - The Response: The origin server generates the user's private profile page and sends it back. Crucially, if the origin doesn't explicitly tell the cache not to store this (via
Cache-Controlheaders), the cache sees the.cssextension and saves the private profile data in its storage under the key/api/user/profile/test.css. - The Theft: The attacker now simply visits
https://example.com/api/user/profile/test.css. The cache sees a "hit" for that URL and serves the stored private data of the victim to the attacker.
Web Cache Deception vs. Web Cache Poisoning
It is common to confuse Web Cache Deception with Web Cache Poisoning, but they are fundamentally different:
- Web Cache Poisoning: The attacker sends a malicious input (like a header) that causes the cache to store a harmful response (like an XSS payload) which is then served to other users. The goal is to distribute a payload.
- Web Cache Deception: The attacker tricks the cache into storing a legitimate but private response from a victim and making it available to the attacker. The goal is data exfiltration.
Common Exploitation Techniques
Exploiting WCD requires finding the right "delimiter" or path structure that causes the origin and the cache to disagree. Here are the most common methods.
1. Simple Path Mapping
As seen in the previous example, this involves adding a slash followed by a static extension.
Example URL: https://example.com/settings.php/nonexistent.jpg
If the server processes settings.php and ignores the rest, but the cache sees .jpg, the attack succeeds.
2. Using Delimiters (Semicolons and Questions Marks)
Some servers treat certain characters as delimiters for parameters or path segments. If the cache and the origin treat these characters differently, WCD can occur.
Example Payload: https://example.com/profile;test.css
In this scenario, the origin server might see the semicolon and truncate the path to /profile. However, the cache might see the whole string and conclude that the file is a CSS file because it ends in .css.
3. Encoded Characters
Attackers often use URL encoding to bypass basic filters.
Example Payload: https://example.com/account%2Ftest.jpg
If the cache decodes the %2F (a forward slash) and thinks the file is test.jpg, but the origin server handles the encoded character differently, the cache might store the response for the /account page.
Practical Example: Stealing an Anti-CSRF Token
Let's look at a technical breakdown of an HTTP exchange during a WCD attack.
Step 1: The Victim Clicks a Link
The attacker sends a victim a link to: https://vulnerable-site.com/user/settings/styles.css.
Step 2: The Request to the Server
GET /user/settings/styles.css HTTP/1.1
Host: vulnerable-site.com
Cookie: session=victim_session_cookie
Step 3: The Origin Response
The origin server ignores /styles.css and returns the settings page, which includes a sensitive CSRF token.
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<html>
<body>
<h1>User Settings</h1>
<input type="hidden" name="csrf_token" value="a7b8c9d0e1f2">
<p>Email: victim@example.com</p>
</body>
</html>
Step 4: The Cache Stores the Data
Because the URL ended in .css, the CDN caches this HTML response. Now, anyone who requests /user/settings/styles.css will receive this HTML content.
Step 5: The Attacker Collects the Data
The attacker makes the same request without the victim's cookie:
GET /user/settings/styles.css HTTP/1.1
Host: vulnerable-site.com
Result: The CDN returns the cached HTML, and the attacker now has the victim's CSRF token and email address.
The Impact of Web Cache Deception
The impact of WCD is primarily related to Information Disclosure. Depending on what is stored on the page being cached, the consequences can range from minor to catastrophic:
- Personally Identifiable Information (PII) Leakage: Names, addresses, phone numbers, and emails can be harvested.
- Session Hijacking: If the application reflects session IDs or security tokens in the HTML body, an attacker can take over the user's account.
- CSRF Protection Bypass: By stealing CSRF tokens, an attacker can perform unauthorized actions on behalf of the user.
- API Key Exposure: Many modern dashboards display API keys or secrets. WCD can leak these to unauthorized parties.
How to Detect Web Cache Deception
Detecting WCD requires testing how your caching layer interacts with your origin server.
Manual Testing Steps:
- Identify a page that displays private information (e.g.,
/profile). - Append a static extension to the URL (e.g.,
/profile/test.css). - Check if the page still loads correctly with your private data.
- Logout or use a different browser/incognito mode and visit the exact same URL (
/profile/test.css). - If you see the private data from the previous session, the site is vulnerable.
Automation and Monitoring:
Security teams use infrastructure reconnaissance tools to identify the presence of caching headers like X-Cache, CF-Cache-Status, or Age. Monitoring these headers across your entire attack surface is crucial for identifying misconfigured caching rules.
Mitigation and Prevention Strategies
Preventing Web Cache Deception involves ensuring that the cache and the origin server are perfectly aligned in how they handle requests.
1. Set Proper Cache-Control Headers
This is the most effective defense. The origin server should explicitly tell the cache not to store sensitive pages. Use the following header for all dynamic content:Cache-Control: no-store, private
This tells the cache that the response contains private data and should never be saved or shared with other users.
2. Use "Strict" Path Handling
Configure your web server so that it does not ignore trailing path segments. If a user requests /profile/test.css and /profile/test.css does not exist as a literal file, the server should return a 404 Not Found rather than falling back to /profile.
3. Cache Only by Content-Type
Instead of relying on file extensions in the URL, configure your CDN to cache based on the Content-Type header returned by the origin. If the response is text/html, it shouldn't be cached as a static asset, even if the URL ends in .css.
4. Disable Path Mapping Features
In frameworks like Spring (Java), features like "suffix pattern matching" are often enabled by default. Disabling these features ensures that the application only responds to the exact intended routes.
Conclusion
Web Cache Deception highlights the dangers of "middleman" components in web architecture. While CDNs and caches provide immense performance benefits, they introduce a layer of logic that must be synchronized with the backend. By understanding the discrepancy between how paths are parsed, attackers can turn a performance tool into a data exfiltration engine.
To proactively monitor your organization's external attack surface and catch exposures before attackers do, try Jsmon. Identifying misconfigured caching headers and exposed endpoints is a critical step in defending against Web Cache Deception and other infrastructure-level vulnerabilities.