HTTP/2 Request Smuggling - Eine Einführung

HTTP/2 Request Smuggling

Eine Einführung

Andrea Hauser
von Andrea Hauser
am 07. Juli 2022
Lesezeit: 8 Minuten

Keypoints

So funktioniert HTTP/2 Request Smuggling

  • Request Smuggling entsteht dann, wenn sich in einer Kette von Servern die Server nicht einig sind, wo der Request-Body endet
  • HTTP/1.1 und HTTP/2 basieren auf unterschiedlichen Prinzipien
  • Fehlerhafte Umwandlung von einem HTTP/2 zu einem HTTP/1.1 Request können von Angreifern ausgenutzt werden
  • Eine durchgehende HTTP/2 Verbindung, also auch zwischen Front-End und Back-End behebt das Problem

Im vorhergehenden Artikel wurden die Grundlagen des Request Smugglings erklärt. Diese werden für die nachfolgenden Erklärungen notwendig sein, wer Request Smuggling noch nicht kennt, sollte also zuerst den Artikel zu Request Smuggling – Beschreibung und Vorgehen beim Testen lesen.

HTTP/2 ist ein binäres Protokoll. Dabei werden HTTP/2-Nachrichten in einem, bis mehreren Frames versandt und jeder Frame hat eine explizite Länge, die dem Server vorgibt, wie viele Bytes gelesen werden sollen. Die Länge einer HTTP/2-Nachricht wird dementsprechend berechnet in dem die Länge aller Frames aufsummiert wird. Diese Länge kann nicht manipuliert werden. Nun stellt sich die Frage, wie in HTTP/2 dennoch Request Smuggling entstehen kann, wenn die Länge der Frames nicht manipuliert werden kann, da diese Manipulation der Länge bei HTTP/1.1-Anfragen die Voraussetzung für das Request Smuggling war. Grundsätzlich entsteht HTTP/2 Request Smuggling nur dann, wenn das Front-End HTTP/2 spricht, das Back-End allerdings nicht. Dann muss das Front-End die HTTP/2-Anfrage für das Back-End in eine HTTP/1.1-Anfrage umwandeln. Hier entstehen dann neue Möglichkeiten für Manipulationen.

Da HTTP/2 ein binäres Protokoll ist, werden hier abstrahierte und vereinfachte Darstellungen verwendet, um die Konzepte aufzuzeigen. Die einzelnen Frames werden nicht aufgezeigt. In HTTP/2 existieren sogenannte Pseudoheader. Diese werden für den weiteren Verlauf des Artikels wie folgt definiert und mit einem Doppelpunkt vor dem Namen als solche gekennzeichnet:

Pseudoheader Beschreibung
:method Entspricht der Request Methode.
:path Entspricht dem Request Pfad inklusive möglichen Parametern.
:authority Entspricht ungefähr dem Host Header.
:scheme Entspricht dem Request Schema und ist im Normalfall http oder https.
:status Entspricht dem Response Status Code und wird in Requests nicht verwendet.

Am einfachsten ist es diese Header im Einsatz zu sehen im Vergleich zur gleichen Anfrage in HTTP/1.1 und HTTP/2.

HTTP/1.1 Request

POST /test HTTP/1.1\r\n
Host: example.com\r\n
User-Agent: test\r\n
Content-Length: 3\r\n
\r\n
x=1

HTTP/2 Request

:method POST
:path /test
:authority example.com
:scheme https
user-agent test
x=1

Mit den Grundlagen abgedeckt können nun die HTTP/2 Request Smuggling-Schwachstellen angegangen werden.

H2.CL Schwachstelle

Diese Schwachstelle funktioniert vom Prinzip her ähnlich wie die TE.CL Schwachstelle aus dem letzten Artikel, allerdings verwendet das Front-End HTTP/2, ignoriert den Content-Length Header und gibt ihn unverändert an das Back-End weiter. Das Back-End verwendet HTTP/1.1 und interpretiert daher den Content-Length Header. In einem Beispiel sieht der Angriff wie folgt aus.

:method POST
:path /test
:authority example.com
content-type application/x-www-form-urlencoded
content-length 0
Injected

Da das Back-End die Verarbeitung der Anfrage aufgrund der Content-Length von 0 früher beendet, als das Front-End geschickt hat, bleibt der Rest der Anfrage in der Pipeline zwischen Front-End und Back-End bestehen. Sobald eine nächste Anfrage eintrifft, wird der noch in der Pipeline vorhandene Rest der vorherigen Anfrage vor dieser neuen Anfrage hinzugefügt. Eine neue Anfrage würde im Back-End also wie folgt aussehen.

InjectedGET /user-requested HTTP/1.1
Host: example.com

H2.TE Schwachstelle

Ähnlich wie bei der oben beschriebenen Schwachstelle verwendet das Front-End HTTP/2, ignoriert den Transfer-Encoding Header und gibt ihn unverändert an das Back-End weiter. Das Back-End verwendet HTTP/1.1 und interpretiert daher den Transfer-Encoding Header. In einem Beispiel sieht der Angriff wie folgt aus.

:method POST
:path /test
:authority example.com
content-type application/x-www-form-urlencoded
transfer-encoding chunked
0

GET /admin HTTP/1.1
Host: example.com
Foo: Injected

Da das Back-End die Verarbeitung der Anfrage aufgrund des Transfer-Encoding von 0 früher beendet, als das Front-End geschickt hat, bleibt der Rest der Anfrage in der Pipeline zwischen Front-End und Back-End bestehen. Sobald eine nächste Anfrage eintrifft, wird der noch in der Pipeline vorhandene Rest der vorherigen Anfrage vor dieser neuen Anfrage hinzugefügt. Eine neue Anfrage würde im Back-End also wie folgt aussehen.

POST /test HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

0
--> Anfrage eins endet hier
GET /admin HTTP/1.1
Host: example.com
Foo: InjectedGET /user-requested HTTP/1.1

Request Smuggling mit CRLF-Injektion

Da HTTP/2 und HTTP/1.1 nicht auf der gleichen Basis interpretiert werden, da HTTP/2 ein binäres Protokoll ist und HTTP/1.1 String basiert ist, können diese Unterschiede ausgenutzt werden. In einem HTTP/2 Header können zum Beispiel problemlos Zeilenumbrüche genutzt werden, da diese nicht speziell interpretiert werden. Das heisst aus einem im Front-End als ein Header interpretierten Header können im Back-End mehrere Header werden. Zum Beispiel wäre

Testheader: Test\n\rInjected

im Front-End ein Header, würde im Back-End allerdings wie folgt aussehen

Testheader: Test
Injected

Danke der ausgezeichneten Forschung von James Kettel können die oben beschriebenen Angriffe in der Web Security Academy nachgespielt werden.

Gegenmassnahmen

Diese Schwachstelle kann, wie zu Beginn bereits angedeutet, am einfachsten verhindert werden, in dem durchgehend HTTP/2 eingesetzt wird. Falls dies nicht möglich ist, muss darauf geachtet werden, dass bei der Umwandlung in einen HTTP/1.1 Request keine Header wie Content-Length oder Transfer-Encoding und keine Spezialzeichen wie \r\n und : übernommen werden.

Fazit

Bei der Umstellung auf HTTP/2 im Front-End Server kann unbewusst eine weitreichende Schwachstelle eingeführt werden, wenn sich die HTTP/2 und die HTTP/1.1 sprechenden Server nicht einig sind, wo die Grenze des Requests sind. Die Auswirkungen von Request Smuggling könne das unberechtigte Lesen von Responses von anderen Benutzern, das Einfügen von beliebigem JavaScript in beliebige Responses von Benutzern, sowie das vollständige Stören eines normalen Betriebs einer Webseite sein. Die Behebung ist vergleichsweise einfach, wenn der Back-End Server ebenfalls auf HTTP/2 umgestellt werden kann. Ansonsten benötigt es eine sorgfältige Umwandlung der Requests, um keine Schwachstellen einzuführen.

Über die Autorin

Andrea Hauser

Andrea Hauser hat ihren Bachelor of Science FHO in Informatik an der Hochschule für Technik Rapperswil abgeschlossen. Sie setzt sich im offensiven Bereich in erster Linie mit Web Application Security Testing und der Umsetzung von Social Engineering Kampagnen auseinander. Zudem ist sie in der Forschung zum Thema Deepfakes tätig. (ORCID 0000-0002-5161-8658)

Links

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

×
Angriffsmöglichkeiten gegen Generative AI

Angriffsmöglichkeiten gegen Generative AI

Andrea Hauser

XML-Injection

XML-Injection

Andrea Hauser

Burp Makros

Burp Makros

Andrea Hauser

WebSocket Fuzzing

WebSocket Fuzzing

Andrea Hauser

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv