Skip to main content
  1. Blog Posts/

Web Cache Poisoning

··1030 words·5 mins

Guide 12 in Sarah’s Welcome to Web Security Series #

In this series, Sarah discusses some common vulnerability classes found in web security and how you can find and exploit them. Today’s focus is web cache poisoning, a complex class of attacks that exploits web caches to deliver malicious HTTP responses to other users.

Introduction #

The idea of a web cache poisoning attack is fairly simple: An attacker can take advantage of a web cache to store some malicious HTTP which is then distributed to users, instead of real content from the web page’s server.1 In reality, this attack is fairly uncommon due to how difficult it is to actually execute, though when it is used, it is often used to exploit a secondary vulnerability like XSS. This is mostly because there are a large number of conditions that need to be met in order for the attack to work. However, if successful, a web cache poisoning attack can have significant ramifications due to the fact that many users will probably visit the poisoned cache and thus be a victim of some malicious content. The malicious content will persist until the cache is completely purged.

Finding Unkeyed Inputs #

The cornerstone of a web cache poisoning attack is the presence of unkeyed inputs, like headers. This is because such inputs are ignored by the web cache (because they are not a part of the cache key) when determining whether or not the cached response should be sent to the user. To actually find unkeyed inputs, one can either do so manually by adding a bunch of random input to requests and seeing if anything changes or use some tool, like BurpSuite’s Param Miner extension, to do the same thing but in a much less tedious fashion.2 A common target is the X-Forwarded-Host header because it’s used for reverse proxies and/or load balancing, though incorrect validation can lead to it being vulnerable. Note that the changes in the request can be subtle, or obvious, but once you have found your inputs, you have to determine how it is being processed. Is it being reflected? Is it used to generate some other part of the web page? Is it being executed as code somewhere in the browser? Once an attacker has an idea of how the input is being processed, they can move on to crafting a malicious payload.

Poisoning the Web Cache #

With the malicious payload in place within the unkeyed input, an attacker now has to poison the cache itself, i.e. get it stored in the cache in place of the legitimate response. This is actually the difficult part as, depending on the content type, response headers, route, server set-up, file type and a myriad of other actors, the cache might not actually store the poisoned response. A fair amount of time has to be spent simply analysing the cache’s behaviour to see what has to be done for it to cache the poisoned response. An attacker has to successfully manipulate the web cache’s mechanisms to actually poison it. Once again, this, like many other things in web security, becomes a simple case of throwing pasta at the wall and seeing what sticks.3 However, once it has been injected in the cache, the cache should begin serving the malicious content out to users every time a request is sent.

Defending Against Web Cache Poisoning #

The simple answer is disable caching. However, with sites that have a lot of traffic, this is simply not feasible so the next best thing is to have a good caching policy, as it is a good policy that makes poisoning the cache difficult. This means the requirements for what content to cache, how it should be cached, for how long it can be cached. etc are strictly enumerated, to make it difficult for attackers to slip in their own content. Beyond that, cache key normalisation (i.e. uniform formatting) and cache control headers (to specify what can be cached) can also be established. Other general defences, such as validation and sanitation of user input, monitoring the cache and strong web application firewalls (WAFs) can also be effective defence mechanisms against web cache poisoning.

Conclusion #

Although web cache poisoning is a fairly rare occurrence, given how difficult it is to pull off, it can have widespread effects if done correctly, which is why cybersecurity professionals must still keep an eye out for signs of poisoning. Moreover, the use of caching in web applications is extremely widespread, so even if only 0.001% of poisoning attempts are successful, that is still a significant number of potential victims. Therefore, even if the chances of success are slim, a prospecting web penetration tester should still test for web cache poisoning vulnerabilities. After all, it never hurts to try

If you are interested in learning more about web cache poisoning and web security, the WebSecurity Academy is a fantastic resource. You can create a free account and explore their labs here.

  1. A web cache is a collection of pre-calculated/pre-determined data from a web page. It helps the page load faster so that users do not have to spend ages waiting for stuff to ‘load in’ every time they visit a web page. Every cache also has a cache key, which is used to see if the cache is currently storing what needs to be retrieved essentially. The key just contains some part of the (original) request as well as the host header and request line. If the key matches the request, it means the cache can simply send that it has back as a response. Consider some pizza shop that takes orders. Most of its customers order a margherita pizza so rather than making them to order, the shop just makes a whole bunch (“a cache of pizza”) and any time an order contains the words “margherita pizza” (our fictional cache key), they just send out one of the pizzas from the cache. That’s basically how a web cache works. ↩︎

  2. To continue our pizza shop analogy, this is like a customer ordering “100000000 margherita pizza”, a “large margherita”, a “mARgHErita pizea” and a “get margherita pwned pizza”. ↩︎

  3. You know what I’m going to say. ↩︎