HTTP-Request-Smuggling verständlich erklärt
Sam Sanoop
30. Juni 2020
0 Min. LesezeitHTTP-Request-Smuggling ist eine interessante Schwachstellenart, die im vergangenen Jahr zunehmend bekannt geworden ist. Angreifer können dabei bestimmte Funktionen des HTTP/1.1-Protokolls ausnutzen, um Sicherheitsmaßnahmen zu umgehen, Phishing-Angriffe durchzuführen und sensible Informationen aus Anfragen anderer Nutzer abzurufen.
Request-Smuggling hat in den letzten Monaten auch in der Community viel Aufmerksamkeit erhalten, unter anderem durch zahlreiche hoch dotierte Bug-Bounty-Meldungen. Snyk hat festgestellt, dass im Jahr 2020 bislang 18 Abhängigkeiten betreffende HTTP-Request-Smuggling-Schwachstellen veröffentlicht wurden.
Diese Schwachstelle wurde erstmals 2005 von Watchfire im Whitepaper „HTTP Request Smuggling“ behandelt. Später wurde die Arbeit von dem Forscher Regis Leroy erweitert und von James Kettle von Portswigger Security auf der BlackHat USA 2019 weiter erörtert, was zusätzliche Aufmerksamkeit in den Medien erregte.
Dieser Blogbeitrag erklärt die Schwachstelle und gibt Open-Source-Projektverantwortlichen konkrete Hinweise, wie sie HTTP-Request-Smuggling in ihren Projekten beheben können.
Hintergrund
Wenn neue Angriffe und Schwachstellen bekannt werden und in den Medien Aufmerksamkeit erhalten, geraten Open-Source-Bibliotheken häufig ins Visier von Angreifern. Aufgrund fehlenden Wissens zur Behebung kann es Wochen oder sogar Jahre dauern, bis diese Schwachstellen in den Bibliotheken angemessen behoben sind. Um die Open-Source-Community sicherer zu machen, untersucht das Snyk Security Team häufig Schwachstellen wie HTTP-Request-Smuggling. Dabei identifiziert es Schwachstellen in Open-Source-Abhängigkeiten und gibt den Maintainerinnen und Maintainer konkrete Empfehlungen zu deren Behebung.
Snyk untersuchte die Auswirkungen von HTTP-Request-Smuggling im Ökosystem der Open-Source-Abhängigkeiten und entdeckte dabei zahlreiche Schwachstellen. Weitere Informationen zu den entdeckten Schwachstellen finden Sie hier.
Snyk stellte fest, dass es nur wenige öffentliche Quellen mit geeigneten Anleitungen zur Behebung von HTTP-Request-Smuggling gibt. Außerdem benötigten Maintainer mehrere Releases, um die Schwachstelle angemessen zu beheben. Mit diesem Blogbeitrag möchten wir diese Lücke schließen und allen Maintainerinnen und Maintainer, die Hilfe zu diesem Thema suchen, detaillierte Empfehlungen zur Behebung geben.
HTTP-Request-Smuggling erklärt
Um HTTP-Request-Smuggling zu verstehen, müssen Sie zunächst die folgenden Bereiche kennen:
Keep-Alive und Pipelining
Das Konzept von Keep-Alive und Pipelining wurde erstmals in RFC 2616 veröffentlicht.
Der Keep-Alive-Header ist ein Hop-by-Hop-Header, der Informationen zu einer dauerhaften Verbindung bereitstellt. In Webservern lässt sich Keep-Alive im „Connection“-Header angeben, damit der Webserver einen TCP-Socket bzw. eine Verbindung offen halten kann. Mit diesem Header können mehrere Anfragen und Antworten über eine einzige Verbindung übertragen werden. Das kann den Overhead verringern und die Leistung des Webservers verbessern. Diese Funktion wird heute von allen Browsern und Servern unterstützt.
Pipelining ist eine weitere Funktion, die mit RFC 2616 eingeführt wurde. Damit kann ein Webserver Anfragen asynchron als First-in-first-out-Datenstrom verarbeiten, anstatt jede Anfrage einzeln zu bearbeiten. So kann er eine Anfrage senden, ohne auf die Antwort auf eine vorherige Anfrage zu warten.
Content-Length und Transfer-Encoding
HTTP-Anfragen können einen Nachrichtenkörper enthalten. Ob eine Anfrage einen Nachrichtenkörper enthält, wird über ein Content-Length- oder Transfer-Encoding-Headerfeld signalisiert. Diese Header dienen der Nachrichtenabgrenzung und teilen dem Server mit, wo eine Nachricht endet und die nächste beginnt.
Content-Length ist in RFC 7230, Abschnitt 3.3.2 definiert und gibt als HTTP-Header die Größe des Nachrichtenkörpers einer Anfrage an. Dieser Header ist häufig in HTTP-POST-Anfragen mit einem Datenkörper zu finden. GET-Anfragen sollten in der Regel keinen Content-Length-Header enthalten, da sie keinen Nachrichtenkörper haben.
Transfer-Encoding ist ebenfalls in RFC 7230 definiert und wurde eingeführt, um Binärdaten über HTTP zu übertragen. Transfer-Encoding umfasst mehrere Direktiven. In diesem Blogbeitrag geht es um die Direktive „chunked“.
Mit der Direktive „chunked“ können Daten in einer Reihe von Chunks übertragen werden. Die Länge dieser Chunks wird im Hexadezimalformat angegeben, gefolgt von einem Wagenrücklauf und einem Zeilenvorschub. Das Ende einer „chunked“-Übertragung wird durch 0 und eine leere Sequenz angezeigt. Ein Beispiel für eine „chunked“-Anfrage sehen Sie unten.
Request-Smuggling
Ein moderner Webserver-Stack umfasst oft mehrere Webserver sowie Load Balancer und WSGI-Server. Ein einfaches Diagramm dazu sieht folgendermaßen aus:

HTTP-Request-Smuggling-Schwachstellen entstehen, wenn Frontend und Backend die Grenze einer HTTP-Anfrage unterschiedlich interpretieren und dadurch ihre Verarbeitung nicht mehr synchron ist. Ursache sind zahlreiche Frontend- und Backend-Bibliotheken, die bei der Verarbeitung von Content-Length- und Transfer-Encoding-Headern von den RFC-Vorgaben abweichen. HTTP-Nachrichtenkörper können anhand dieser beiden Header abgegrenzt werden; dabei kommt es zu Abweichungen von der Spezifikation. Infolgedessen wird ein Teil der Anfrage an die nächste angehängt oder in sie eingeschleust. Dadurch kann die Antwort auf die eingeschleuste Anfrage an einen anderen Nutzer ausgegeben werden.
Diese Schwachstelle lässt sich für Phishing-Angriffe, Cache-Poisoning, Cross-Site-Scripting (XSS) und mehr ausnutzen. Weitere Informationen zur Ausnutzung dieser Schwachstelle veröffentlichte James Kettle im vergangenen Jahr auf der BlackHAT USA 2019 unter dem Titel „HTTP Desync Attacks: Request Smuggling Reborn“. In diesem Blogbeitrag geht es um die beiden gängigsten Request-Smuggling-Techniken:
CL:CL: Angriffstechnik mit doppeltem Content-Length
CL:TE: Angriffstechnik mit Content-Length und Transfer-
Encoding-Angriffstechnik
CL:CL: Angriffstechnik mit doppeltem Content-Length
Laut RFC 7230, Abschnitt 3.3.3#4:
„Wenn eine Nachricht ohne Transfer-Encoding und mit mehreren Content-Length-Headerfeldern mit unterschiedlichen Feldwerten oder einem einzelnen Content-Length-Headerfeld mit einem ungültigen Wert empfangen wird, ist die Nachrichtenabgrenzung ungültig. Der Empfänger MUSS sie als nicht behebbaren Fehler behandeln.“
Die meisten Middleware-Komponenten und Webserver verarbeiten GET-Anfragen mit Nachrichtenkörper derzeit jedoch recht großzügig. Außerdem heißt es in RFC 7231, Abschnitt 4.3#4.3.1: „Ein Payload in einer GET-Anfragenachricht hat keine definierte Semantik. Das Senden eines Payload-Nachrichtenkörpers in einer GET-Anfrage kann dazu führen, dass manche vorhandenen Implementierungen die Anfrage ablehnen.“ Das deutet darauf hin, dass viele Server und Proxys dieses Verhalten unterstützen könnten. In manchen Fällen kann dies Request-Smuggling-Angriffe ermöglichen. In diesem Blogbeitrag betrachten wir eine Variante dieses Angriffs.
Wenn zwei Content-Length-Header übermittelt werden und Frontend und Backend unterschiedliche Header priorisieren, kann es zu Smuggling-Angriffen kommen.

Bei der oben dargestellten HTTP-Anfrage werden zwei Content-Length-Header an ein Ziel gesendet, dessen Frontend aus einem Proxy oder Load Balancer besteht. Der Proxy berücksichtigt den ersten Content-Length-Header und priorisiert ihn. Daher behandelt er die eingeschleuste Anfrage als Teil des Nachrichtenkörpers, obwohl eine GET-Anfrage keinen Nachrichtenkörper enthalten sollte und zwei Content-Length-Header angegeben sind. Bei der Verarbeitung durch das Backend wird der erste Content-Length-Header ignoriert und der zweite priorisiert. Da der zweite Content-Length-Wert auf null gesetzt ist, erwartet das Backend keinen Nachrichtenkörper und behandelt die Anfrage /reqsmuggle als weitere pipelined Anfrage. Dadurch kann ein anderer Nutzer die Antwort auf diese eingeschleuste Anfrage erhalten.
CL:TE: Angriffstechnik mit Content-Length und Transfer-Encoding
Bei dieser beliebten Technik, die von James Kettle von PortSwigger Labs entdeckt wurde, werden ein Content-Length- und ein Transfer-Encoding-Header in eine einzelne HTTP-Anfrage eingefügt. Anschließend werden sie so manipuliert, dass ein Frontend-Proxy und ein Backend-Server die Header unterschiedlich priorisieren und die eingeschleuste Anfrage verschieden verarbeiten. Eine Beispielanfrage, die diese Schwachstelle veranschaulicht, sieht folgendermaßen aus.
Bei der Verarbeitung dieser Anfrage durch einen Frontend-Proxy wird der Content-Length-Header berücksichtigt und gegenüber dem Transfer-Encoding-Header priorisiert. Der Backend-Server priorisiert jedoch den Transfer-Encoding-Header. Daher verarbeitet das Backend die Anfrage bis zum Zeichen 0. Infolgedessen wird die 404-GET-Anfrage als separate pipelined Anfrage behandelt.
Das Problem entsteht, weil das Frontend den Content-Length-Header gegenüber dem Transfer-Encoding-Header priorisiert. Laut RFC 7230, Abschnitt 3.3.3#3, hat bei einer akzeptierten Nachricht mit Content-Length und Transfer-Encoding der Transfer-Encoding-Header Vorrang vor Content-Length. Das Frontend hält sich nicht daran.

Wenn das Frontend den Transfer-Encoding-Header priorisiert, lässt sich diese Einschränkung möglicherweise umgehen, indem statt eines gültigen ein fehlerhaft formatierter Transfer-Encoding-Header eingefügt wird. Einige Beispiele sehen Sie unten:
Zahlreiche HTTP-Bibliotheken akzeptieren verschiedene Varianten des Transfer-Encoding-Headers und normalisieren sie, um die Benutzerfreundlichkeit zu verbessern. Wenn Sie wissen, welche Varianten des Transfer-Encoding-Headers der Backend-Server normalisiert, können Sie möglicherweise einen fehlerhaft formatierten Transfer-Encoding-Header durch das Frontend einschleusen und einen CL:TE-Smuggling-Angriff durchführen.
Die obigen Beispiele veranschaulichen lediglich die Schwachstelle. Bei einem echten Angriff kann eine eingeschleuste Anfrage so gestaltet werden, dass sie Phishing-Angriffe ermöglicht oder Daten aus der Anfrage eines Opfers stiehlt und an einen vom Angreifer kontrollierten Server sendet.
Umfang und Missverständnisse
Im Rahmen dieser Untersuchung stellte Snyk zahlreiche Fälle fest, in denen die offensichtliche Komplexität der verschiedenen Angriffsvektoren zu Missverständnissen führte. Forschende und Maintainer meldeten Open-Source-Maintainern HTTP-Request-Smuggling-Schwachstellen, ohne immer zu verstehen, ob die Behebung in den Zuständigkeitsbereich der betreuten Bibliothek fällt oder von einer verwendeten Abhängigkeit übernommen werden sollte.
Einige Punkte, die einer genaueren Erläuterung bedurften, waren:
Proxys, Load Balancer und andere Komponenten, die als Frontend gelten, sind am stärksten von dieser Schwachstelle betroffen. Ein erfolgreicher Request-Smuggling-Angriff setzt jedoch voraus, dass sowohl ein verwundbares Frontend als auch ein verwundbares Backend ausgenutzt werden.
Für die Behebung sind Backend- und Frontend-Maintainer gleichermaßen verantwortlich. Man könnte argumentieren, dass ein Backend fehlerhaft formatierte Header normalisieren und Nutzereingaben toleranter behandeln sollte und dass das eigentliche Problem bei Proxys liegt, die solche Anfragen ohne vorherige Normalisierung weiterleiten. Angesichts des umfangreichen Ökosystems an Abhängigkeiten und der zahlreichen Bibliotheken, die sowohl als Backend als auch als Frontend dienen, sollten jedoch beide Seiten versuchen, dieses Problem zu beheben.
Middleware, Webserver mit Reverse-Proxy-Funktionen sowie WSGI- und Hochleistungsserver erfüllen die Kriterien für ein Backend. Ein Webserver, der lediglich fehlerhaft formatierte Anfragen verarbeiten kann, aber kein Pipelining unterstützt, zählt hingegen nicht dazu.
Sicherheitslücken werden Maintainer häufig als HTTP-Request-Smuggling-Probleme gemeldet, weil Server auf mehrere gesendete Anfragen antworten und diese Antworten als zwei separate Antworten sichtbar sind. Viele Server unterstützen Keep-Alive und Pipelining. Das allein stellt jedoch keine HTTP-Request-Smuggling-Schwachstelle dar. Ein Beispiel dafür ist CVE-2020-12440, die für NGINX gemeldet wurde.
Behebung
Probleme mit HTTP-Request-Smuggling entstehen durch Abweichungen von den aktuellen HTTP-Spezifikationen und dadurch, dass mehrere Bibliotheken RFC 7230 nicht befolgen. Außerdem kann die Behebung dieser Schwachstelle schwierig sein – je nachdem, ob Sie ein Frontend- oder Backend-Projekt betreuen. Snyk hat daher untersucht, wie Open-Source-Projekte die Schwachstelle derzeit beheben, und die Ansätze wie folgt kategorisiert. Zur Vereinfachung werden alle Maßnahmen zur Behebung zusammen mit einer Begründung aufgeführt, welcher Art von Smuggling-Angriff sie entgegenwirken. Im Idealfall sollten alle unten genannten Maßnahmen genutzt werden, um einen mehrschichtigen Schutzansatz zu schaffen.
Transfer-Encoding gegenüber Content-Length priorisierenBehebung:Diese Maßnahme verhindert CL:TE- und TE:CL-Angriffe.Geltungsbereich: Frontend, BackendDetails:Wenn eine Anfrage mit einem Transfer-Encoding: chunked-Header und einem Content-Length-Header eingeht, sollte der Transfer-Encoding-Header gegenüber Content-Length priorisiert werden. Dies wird in RFC 7230, Abschnitt 3.3.3#3, beschrieben.
Anfragen mit Content-Length- und Transfer-Encoding-Headern sowie doppelten Content-Length-Headern ablehnenBehebung: Diese Maßnahme verhindert CL:CL-, CL:TE- und TE:CL-Angriffe.Geltungsbereich: Backend, Frontend, Backend, Upstream-BibliothekenDetails: Dies kann als bessere Alternative zur Lösung „Transfer-Encoding gegenüber Content-Length priorisieren“ betrachtet werden. Laufzeitplattformen wie Node.js haben diesen Ansatz verwendet, um Request-Smuggling-Angriffe zu beheben: Anfragen mit beiden Headern werden dabei mit einer HTTP-400-Antwort zurückgewiesen.
Snyk hält diese Methode für eine ideale Lösung, um Smuggling-Probleme zu verhindern. Allerdings sollte berücksichtigt werden, wie die Lösung angewendet wird – insbesondere dann, wenn sie in einer Low-Level-HTTP-Bibliothek oder einer Upstream-Engine umgesetzt wird, von der zahlreiche Pakete, etwa ein Frontend, abhängen.
Bei der Behebung von HTTP-Request-Smuggling-Problemen sollte RFC 7230 #3.3.3 befolgt werden. In Abschnitt 3.3.3#3 von RFC 7230 heißt es:
„Wenn eine Nachricht sowohl mit einem Transfer-Encoding- als auch mit einem Content-Length-Headerfeld empfangen wird, hat Transfer-Encoding Vorrang vor Content-Length. Eine solche Nachricht könnte auf einen Versuch hindeuten, Request Smuggling (Abschnitt 9.5) oder Response Splitting (Abschnitt 9.4) durchzuführen, und sollte als Fehler behandelt werden. Ein Absender MUSS das empfangene Content-Length-Feld entfernen, bevor er eine solche Nachricht an einen nachgelagerten Empfänger weiterleitet.“
Dies unterscheidet sich jedoch von den Vorgaben in RFC 2616 4.4#3:
„Wenn eine Nachricht sowohl mit einem Transfer-Encoding-Headerfeld als auch mit einem Content-Length-Headerfeld empfangen wird, MUSS Letzteres ignoriert werden.“
Beachten Sie, dass RFC 2616 4.4#3 veraltet und durch RFC 7230 ersetzt wurde. Bei der Implementierung einer Lösung sollte RFC 7230 berücksichtigt werden. Bei der Verarbeitung von HTTP-Anfragen mit einem Content-Length- und einem Transfer-Encoding-Header sollte sich das Frontend also korrekt verhalten und den Content-Length-Header entfernen, bevor es die Anfrage an ein nachgelagertes Backend weiterleitet, statt eine HTTP-400-Antwort zurückzugeben. Dasselbe sollte bei Anfragen mit mehreren Content-Length-Headern geschehen, wie in RFC 7230#3.3.2 beschrieben.
Wie in RFC 7230, Abschnitt 3.3.2, erwähnt, kann eine HTTP-Anfrage mit mehreren Content-Length-Headern und unterschiedlichen Längenwerten entweder mit einer HTTP-400-Antwort zurückgewiesen werden oder die doppelten Feldwerte können durch einen einzelnen gültigen Content-Length-Header ersetzt werden. Snyk empfiehlt, dass Low-Level-HTTP-Bibliotheken mehrere Header durch einen einzelnen gültigen Header ersetzen.
Fehlerhafte Transfer-Encoding-Header ablehnen und mehrere TE-Werte korrekt verarbeitenBehebung:Diese Maßnahme verhindert TE:TE-Angriffe.Geltungsbereich: Frontend, BackendDetails:Wenn sowohl ein Frontend als auch ein Backend den Transfer-Encoding-Header priorisieren, können Smuggling-Angriffe möglich sein: Ein Angreifer fügt zwei Transfer-Encoding-Header ein, von denen einer vom Frontend ignoriert und vom Backend verarbeitet wird – oder umgekehrt. Daher sollten die folgenden Arten von Header-Variationen abgelehnt werden.

Beachten Sie jedoch, dass Angreifer weiterhin nicht dokumentierte fehlerhafte Varianten der „chunked“-Kodierung finden können. Daher sollte diese Maßnahme allein nicht als ausreichende Behebung betrachtet werden. Besser ist es, Anfragen mit Content-Length und Transfer-Encoding abzulehnen und zusätzlich fehlerhafte Header zurückzuweisen.
Abschließend ist zu beachten, dass der Wert „chunked“ nicht übersehen werden darf, wenn er zusammen mit anderen Transfer-Encoding-Werten wie „gzip“ oder „deflate“ angegeben wird. Transfer-Encoding sollte gegenüber Content-Length priorisiert werden. Ein Beispiel für diese Schwachstelle ist CVE-2019-16786. Wird eine HTTP-Anfrage mit den folgenden Transfer-Encoding-Werten gesendet, sollte der Wert „chunked“ korrekt erkannt und priorisiert werden:
Transfer-Encoding: gzip, chunked
In einem Transfer-Encoding-Header können mehrere durch Kommas getrennte Werte aufgeführt werden. Es kann jedoch vorkommen, dass ein Frontend nur den Wert „gzip“ erkennt und deshalb den Content-Length-Header priorisiert, während das Backend die Anfrage als chunked verarbeitet. Das führt zu einem CL:TE-Angriff. Snyk empfiehlt, mehrere angegebene Werte korrekt zu prüfen und Transfer-Encoding zu priorisieren, wenn „chunked“ enthalten ist. Außerdem darf bei mehreren Transfer-Encoding-Headern der Wert „chunked“ nur als letzter Wert nach den anderen Transfer-Encoding-Werten stehen. Dies ist in RFC 7230, Abschnitt 3.3.1 festgelegt.
Zusammenfassung
Zusammenfassend lässt sich sagen, dass HTTP-Request-Smuggling eine schwer verständliche Schwachstelle sein kann, deren Behebung ebenfalls schwierig ist. Dieser Blogbeitrag soll Maintainer dabei unterstützen, effiziente Patches zu schreiben und ihre Open-Source-Projekte abzusichern.
Beachten Sie auch, dass dieser Blogbeitrag nur zwei Techniken des HTTP-Request-Smugglings behandelt und keine detaillierten Informationen zu verschiedenen Angriffsszenarien enthält. Der folgende Artikel des Sicherheitsforschers ZeddYu behandelt HTTP-Request-Smuggling ausführlich und erläutert die einzelnen Angriffsvektoren im Detail: Zeddy Yu: HTTP Smuggling in einem Artikel verstehen.
Starten Sie mit Capture the Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Herausforderungen lösen.



