HTTP request smuggling
| Po angielsku | HTTP request smuggling |
|---|---|
| Którą formą pisać | po angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim. |
| Inne formy | przemycanie żądań HTTP · request smuggling |
| Kategoria | Podatności i klasy błędów |
HTTP request smuggling to technika zakłócania sposobu, w jaki serwis przetwarza sekwencje żądań HTTP otrzymywanych od jednego albo wielu użytkowników [1]. Wykorzystuje to, że serwer pośredniczący i serwer docelowy różnie ustalają, gdzie kończy się jedno żądanie, a zaczyna następne [1]. MITRE katalogizuje ją jako CWE-444: pośrednik przekazuje dalej zniekształcone żądania i interpretuje je inaczej niż serwer, do którego trafiają [3]. Sekurak opisuje ją po polsku jako „przemycanie” żądań HTTP, które pozwala na przykład dostać się do panelu administracyjnego bez uwierzytelnienia albo wstrzyknąć coś innemu użytkownikowi serwisu [5].
Jak działa
Współczesna strona rzadko jest jednym serwerem. Kettle zwraca uwagę, że nowoczesne serwisy to łańcuchy systemów komunikujących się przez HTTP [4]. Przed aplikacją stoi zwykle reverse proxy, CDN albo load balancer, który utrzymuje z serwerem docelowym długotrwałe połączenia i przesyła nimi żądania wielu użytkowników po kolei.
W HTTP/1.1 długość treści żądania można określić na dwa sposoby: nagłówkiem Content-Length albo nagłówkiem Transfer-Encoding z kodowaniem chunked [1]. RFC 9112 rozstrzyga konflikt: gdy wiadomość zawiera oba nagłówki, Transfer-Encoding ma pierwszeństwo, a taka wiadomość może oznaczać próbę request smuggling [2]. Problem pojawia się, gdy dwa serwery w łańcuchu nie stosują tej reguły tak samo. Wtedy jeden uzna część bajtów za koniec bieżącego żądania, a drugi za początek następnego.
POST /formularz HTTP/1.1
Host: example.com
Content-Length: 30
Transfer-Encoding: chunked
Tak wygląda nagłówek wiadomości niejednoznacznej: dwie reguły wskazują różne długości tej samej treści. Pozostałość, której jeden z serwerów nie uznał za część żądania, dokleja się do żądania kolejnego użytkownika tym samym połączeniem. Kettle opisuje to jako możliwość dopisania dowolnej treści na początek następnego, prawidłowego żądania innego użytkownika [4]. Schemat poniżej pokazuje ten przebieg.
Odmiany
PortSwigger nazywa odmiany według tego, który nagłówek honoruje serwer frontowy, a który serwer zaplecza [1].
| Odmiana | Serwer frontowy | Serwer zaplecza |
|---|---|---|
| CL.TE | Content-Length [1] | Transfer-Encoding [1] |
| TE.CL | Transfer-Encoding [1] | Content-Length [1] |
| TE.TE | oba obsługują TE [1] | jeden ignoruje zaciemniony nagłówek [1] |
| obniżanie HTTP/2 | HTTP/2 od klienta [1] | HTTP/1 po przepisaniu [1] |
Odmiana TE.TE wykorzystuje drobne różnice zapisu, takie jak spacje, tabulatory albo powtórzony nagłówek, które jeden serwer akceptuje, a drugi odrzuca [1]. Ostatnia odmiana dotyczy serwisów, które przyjmują HTTP/2, ale do zaplecza przesyłają żądania przepisane na HTTP/1 [1].
W WordPressie
HTTP request smuggling nie jest błędem w kodzie WordPressa, wtyczki ani motywu. To problem infrastruktury przed aplikacją: rozbieżność między serwerem pośredniczącym a serwerem, na którym działa PHP. Dotyczy więc stron WordPress uruchomionych za reverse proxy, CDN, WAF w chmurze albo za load balancerem hostingu.
Z tego powodu wtyczka bezpieczeństwa działająca wewnątrz WordPressa nie ma wglądu w ten atak. Widzi żądanie dopiero po tym, jak serwery w łańcuchu już podzieliły strumień bajtów. Obrona leży po stronie konfiguracji i aktualizacji serwerów pośredniczących, czyli zwykle po stronie firmy hostingowej albo dostawcy CDN.
Zagrożenia i skutki
PortSwigger wymienia wśród skutków ominięcie zabezpieczeń, nieuprawniony dostęp do danych, zatruwanie pamięci podręcznej, wykorzystanie XSS, ominięcie uwierzytelniania klienta i przechwytywanie żądań innych użytkowników [1]. MITRE dodaje możliwość ominięcia zapory, gdy pośrednik i serwer docelowy różnie odczytują zawartość nagłówków [3].
- Zatruwanie pamięci podręcznej: odpowiedź na przemycone żądanie zostaje zapisana pod adresem prawidłowej strony [3].
- Obejście uwierzytelniania i kontroli dostępu, które serwer frontowy stosuje tylko do żądań, które sam rozpoznał [1].
- Przejęcie sesji przez przechwycenie cudzego żądania razem z ciasteczkami [3].
- Podanie innemu użytkownikowi odpowiedzi z XSS (Cross-Site Scripting) bez żadnego kliknięcia z jego strony [1].
Jak się bronić
RFC 9112 pozwala serwerowi odrzucić żądanie zawierające zarówno Content-Length, jak i Transfer-Encoding, albo przetworzyć je wyłącznie według Transfer-Encoding [2]. W obu przypadkach serwer musi zamknąć połączenie po odpowiedzi [2]. Norma wprowadziła też ostrzejsze zasady parsowania, właśnie po to, by utrudnić ten atak [2].
PortSwigger zaleca kilka praktyk [1]:
- używanie HTTP/2 na całej drodze od klienta do zaplecza i unikanie obniżania wersji protokołu;
- normalizowanie niejednoznacznych żądań na serwerze frontowym i odrzucanie pozostałych niejednoznaczności na zapleczu;
- niezakładanie, że dane żądanie nie ma treści;
- zamykanie połączenia po wyjątku na serwerze.
MITRE wymienia dodatkowo ścisłe parsowanie HTTP, zamykanie sesji po każdym żądaniu i zapory aplikacyjne [3]. Dla właściciela strony najważniejsze jest aktualne oprogramowanie serwerów pośredniczących, bo poprawki tej klasy błędów wydają ich producenci.
Historia i przykłady
Technikę po raz pierwszy opisała firma Watchfire w 2005 roku [4]. MITRE wymienia z tego okresu błędy CVE-2005-2088 i CVE-2005-2089, związane z jednoczesnym użyciem Transfer-Encoding i Content-Length [3]. Przez lata klasa ta była pomijana z powodu opinii o trudności i ryzyku szkód ubocznych [4].
Temat wrócił 7 sierpnia 2019 roku, gdy James Kettle z PortSwigger opublikował badanie „HTTP Desync Attacks: Request Smuggling Reborn” [4]. Autor podał, że zarobił w programach bug bounty ponad 70 tysięcy dolarów, w tym dwie nagrody od PayPala w wysokości 18 900 i 20 000 dolarów [4]. Sekurak omówił tę technikę 12 lutego 2020 roku, wskazując na znaczenie jednoczesnego użycia obu nagłówków długości [5]. Nowszym przykładem u MITRE jest CVE-2020-8287 w Node.js, dotyczący zdublowanych nagłówków Transfer-Encoding [3].
Przypisy
5- [1] HTTP request smuggling · PortSwigger Web Security Academy
- [2] RFC 9112: HTTP/1.1 · IETF
- [3] CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling') · MITRE
- [4] HTTP Desync Attacks: Request Smuggling Reborn · PortSwigger Research
- [5] Czym jest HTTP Request Smuggling? Animacja · Sekurak