Zum Inhalt springen

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

↑↓NavigierenEnterÖffnenESCSchließen
Angriffstechniken Glossar

Web Cache Poisoning - Cache-basierter Angriff

Web Cache Poisoning ist ein Angriff bei dem ein Angreifer unkeyed HTTP-Header oder Parameter nutzt um schädliche Inhalte in einen Web-Cache einzuschleusen. Diese gecachten Inhalte werden dann an andere Nutzer ausgeliefert ohne dass der Origin-Server kontaktiert wird. Angriffsvektoren: manipulierte HTTP-Header (X-Forwarded-Host, X-Forwarded-Scheme), fatcookies, Query-String-Parameter. Resultat: XSS, Open Redirect, Denial of Service gegen viele Nutzer gleichzeitig.

Web Cache Poisoning ist eine der heimtückischsten Schwachstellenklassen - ein Angreifer sendet einen einzigen Request, der im Cache landet, und danach erhalten potenziell tausende Nutzer schädliche Inhalte. Kein direkter Zugriff auf andere Nutzer nötig: der Cache übernimmt die Auslieferung.

Cache-Mechanismus und Keyed vs. Unkeyed

Normaler Request-Flow:

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

Nächster Request: Client → CDN → (Cache-Hit!) → gecachte Response (kein Server-Kontakt!)

Cache-Key (was den Cache-Eintrag identifiziert):

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

Unkeyed Inputs (vom Cache ignoriert, aber vom Origin verarbeitet!):

  • 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
  • Bestimmte HTTP-Header (Via, X-Rewrite-URL)
  • Unbekannte Query-Parameter: ?utm_content=<xss>

Angriffsprinzip:

  1. Angreifer sendet Request mit bösem unkeyed Header
  2. Origin-Server verarbeitet diesen Header (z.B. baut URL daraus)
  3. Response enthält Angreifer-Content, wird OHNE den Header gecacht
  4. Andere Nutzer bekommen dieselbe gecachte Antwort

Kritisch: Origin reflektiert unkeyed Inputs in Responses! Beispiel: X-Forwarded-Host → wird 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!):

<script src="https://evil.com/static/analytics.js"></script>

Alle folgenden User erhalten XSS-Payload via Cache!

Variante - Query-Parameter Reflection:

GET /search?term=<script>alert(1)</script>&utm_content=CACHE HTTP/1.1
→ Wenn `utm_content` unkeyed: Response wird gecacht MIT XSS in term-Reflection!

2. Cache Poisoning → Open Redirect

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

→ Gecachter 301-Redirect auf http (statt https) → Downgrade-Angriff + mögliche MITM-Kette

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&evil=injected
  • Manche Server lesen GET-Body als Parameter (non-standard!)
  • Cache keyt nur URL-Query-String, nicht Body
  • GET-Body-Parameter sind “unkeyed”!

4. Cache Key Normalization Bypass

GET /admin HTTP/1.1  ←  Admin-Seite (nicht gecacht wegen Auth)
GET /ADMIN HTTP/1.1  ←  Gleiche Response? Cache normalisiert auf /admin?

Anwendung:

  • Cache normalisiert Port-Nummer weg: :443 ignoriert
  • Cache normalisiert URL-Encoding: %2F = /
  • Angreifer sendet /admin%2F?poison=1 → gecachter Redirect auf /admin/

5. Cache Poisoning → Denial of Service

GET /critical-resource HTTP/1.1
X-Forwarded-Scheme: https  (wenn nur HTTP erlaubt: 400 Error!)
  • Origin antwortet mit 400 Bad Request
  • Cache cached den 400-Error für /critical-resource
  • Alle Users erhalten 400 für alle Requests!
  • Komplette Service-Disruption!

Erkennung im Pentest

1. Burp Extension: param-miner

  • Findet automatisch unkeyed Header und Parameter!
  • Installation: Burp App Store → param-miner
  • Einfacher Start: Rechtsklick → Guess headers/params

2. Manuelles Testing - unkeyed Header identifizieren

a) Cache-Verhalten verstehen:

  • Mehrfacher Request: erstes Mal Cache-Miss (X-Cache: MISS)
  • Zweites Mal: Cache-Hit (X-Cache: HIT)
  • Sicherstellen: uniquen Cache-Buster in URL nutzen: GET /page?cachebuster=abc123

b) Unkeyed Header testen:

GET /page?cb=001 HTTP/1.1
X-Forwarded-Host: test.com
→ Response: enthält "test.com"? (Reflection!)
→ Nächster Request (ohne Header, gleiche URL):
  GET /page?cb=001 HTTP/1.1
  → Immer noch "test.com" in Response? → Header ist UNKEYED!

3. Gefährliche Reflection-Punkte finden

Suchen nach unkeyed Header-Inhalten in Response:

  • <script src="..."> Tags
  • <link href="..."> Tags
  • JavaScript-Variablen: var BASE_URL = "..."
  • Meta-Refresh: <meta http-equiv="refresh" content="0; url=...">
  • Location-Header (bei Redirects)
  • CORS Header (Access-Control-Allow-Origin)

4. Cache-Timing-Analyse

  • Response-Zeit beim Cache-Miss > Cache-Hit?
  • Age-Header: wie lange gecacht?
  • Cache-Control: max-age=…
  • Vary-Header: welche Header beeinflussen Cache-Key?

Wichtige Response-Header für Analyse:

HeaderBedeutung
X-Cache: HIT / MISSCache-Status
Age: <Sekunden>Zeit seit Caching
CF-Cache-Status: HIT / MISS / EXPIREDCloudflare-Status
X-Varnish: <ID>Varnish Cache
Cache-Control: public, max-age=3600Cache-Direktiven
Vary: Accept-Encoding, Accept-LanguageCache-Key-Varianten

Schutzmaßnahmen

1. Unkeyed Header aus Responses entfernen

  • X-Forwarded-Host NIEMALS in URLs oder Scripts reflektieren!
  • Input-Validation: Hostnamen auf Allowlist prüfen
# Nginx - sichere Host-Normalisierung:
set $safe_host $host;  # Nur Host-Header, ignoriert X-Forwarded-*
add_header Content-Security-Policy "default-src 'self'";
# Apache - X-Forwarded-Host blocken:
RequestHeader unset X-Forwarded-Host

2. Cache-Key erweitern (alle relevanten Header einbeziehen)

# Varnish VCL:
sub vcl_hash {
    hash_data(req.url);
    hash_data(req.http.host);
    hash_data(req.http.X-Forwarded-Proto);  // HTTPS vs HTTP
    return (lookup);
}
# Nginx Proxy Cache:
proxy_cache_key "$scheme$request_method$host$request_uri$http_accept_language";

3. Security Headers auf gecachten Responses

# CSP verhindert Auswirkung von Cache-Poisoning → XSS
Content-Security-Policy: default-src 'self'; script-src 'self'
# Verhindert Downgrade via Redirect-Poisoning:
Strict-Transport-Security: max-age=31536000; includeSubDomains

4. Cache nur für sichere Inhalte aktivieren

  • Dynamische Seiten mit User-spezifischen Inhalten: NICHT cachen!
  • Nur statische Assets (JS, CSS, Bilder) aggressiv cachen
  • HTML-Seiten: kurze TTL (max. 1 Minute) oder revalidate

5. Vary-Header korrekt setzen

# Wenn Response von Accept-Language abhängt: in Cache-Key!
Vary: Accept-Language, Accept-Encoding

6. Anomalie-Erkennung

  • Alerts bei unerwarteten X-Forwarded-* Header-Werten
  • WAF-Regel: X-Forwarded-Host ≠ eigener Hostname → blockieren
  • Monitoring: plötzliche Cache-Hit-Rate-Änderungen → mögliche Poisoning-Attacke

Zusammenfassung sichere Architektur

  • Keinen User-Input in gecachten Responses reflektieren
  • Trusted-Proxy-Header nur von bekannten IPs akzeptieren
  • Cache-Key alle request-varianten Inputs einschließen
  • CSP als Last Line of Defense gegen XSS-Auswirkung

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung