web cache poisoning
| Po angielsku | web cache poisoning |
|---|---|
| Którą formą pisać | po angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim. |
| Inne formy | zatrucie pamięci podręcznej · zatruwanie cache'u · zatrucie cache |
| Kategoria | Podatności i klasy błędów |
Web cache poisoning to technika, w której atakujący wykorzystuje zachowanie serwera WWW i pamięci podręcznej tak, by szkodliwa odpowiedź HTTP została podana innym użytkownikom [1]. Atakujący wysyła jedno spreparowane żądanie, a pamięć podręczna zapisuje odpowiedź i serwuje ją każdemu, kto poprosi o ten sam adres. Specyfikacja HTTP opisuje „cache poisoning” jako wstawienie odpowiedzi do pamięci podręcznej przez błędy implementacji, podwyższone uprawnienia lub inne techniki i zauważa, że atak jest szczególnie skuteczny przy pamięciach współdzielonych, które rozsyłają treść do wielu klientów [4]. Pojęcie należy odróżnić od DNS cache poisoning, które dotyczy odpowiedzi serwerów nazw, a nie stron WWW.
Jak działa
Pamięć podręczna musi rozpoznać, że dwa żądania dotyczą tej samej treści. Służy do tego klucz pamięci podręcznej (cache key). RFC 9111 definiuje go jako informacje, na podstawie których pamięć wybiera odpowiedź, złożone co najmniej z metody żądania i docelowego URI [4]. PortSwigger dodaje, że w praktyce klucz obejmuje zwykle wiersz żądania i nagłówek Host [1]. Pozostałe części żądania są „nieobjęte kluczem” (unkeyed): pamięć je ignoruje przy wyborze odpowiedzi [1].
Problem powstaje, gdy aplikacja za pamięcią podręczną używa takiego nieobjętego kluczem elementu do zbudowania odpowiedzi. Atak ma według PortSwiggera dwie fazy: najpierw atakujący wywołuje u serwera odpowiedź z niebezpiecznym ładunkiem (payload), potem doprowadza do jej zapisania w pamięci i podania ofiarom [1]. Pokazuje to schemat poniżej.
Odmiany
Badanie Jamesa Kettle'a z PortSwiggera, opublikowane 9 sierpnia 2018 roku, pokazało praktyczne ataki na nieobjęte kluczem nagłówki, takie jak X-Forwarded-Host, X-Original-URL, X-Rewrite-URL i X-Forwarded-Scheme [2]. Web Security Academy dzieli wykorzystanie na kilka typowych wzorców.
| Wzorzec | Co trafia do pamięci podręcznej |
|---|---|
| odbicie nagłówka w treści | ładunek XSS w HTML strony [3] |
| adres zasobu budowany z nagłówka | odwołanie do skryptu z serwera atakującego [3] |
| treść zależna od ciasteczka | wersja strony wybrana ciasteczkiem atakującego [3] |
| nagłówek nadpisujący ścieżkę lub schemat | przekierowanie albo inna podstrona [2] |
PortSwigger zauważa, że zatrucie przez ciasteczka jest względnie rzadkie w porównaniu z zatruciem przez nagłówki [3]. RFC 9111 wskazuje jako częsty wektor różnice w parsowaniu komunikatów przez serwery pośredniczące i klientów [4]; tę rodzinę błędów opisuje hasło HTTP request smuggling. Pokrewny jest też host header injection, bo nagłówek Host i jego zamienniki często decydują o adresach w odpowiedzi.
W WordPressie
Dokumentacja WordPressa opisuje wtyczki, które zapisują wpisy i strony jako pliki statyczne i serwują je użytkownikom, odciążając serwer, oraz połączenie z systemową pamięcią podręczną typu Varnish [6]. Typowa witryna ma więc kilka warstw pamięci: wtyczkę, reverse proxy na serwerze i CDN przed nim. Każda z nich ma własny klucz, a WordPress i wtyczki budują odpowiedź z danych, których ten klucz może nie obejmować.
Ryzyko rośnie, gdy motyw, wtyczka albo konfiguracja serwera bierze adres witryny z nagłówków żądania zamiast z ustawień. PortSwigger opisuje, że nagłówek X-Forwarded-Host bywa używany do generowania adresów w znacznikach meta i odwołaniach do skryptów [2]. Jeśli pamięć podręczna nie uwzględnia go w kluczu, jedno żądanie może podmienić adresy zasobów na stronie głównej dla wszystkich odwiedzających. Podobnie działa treść zależna od ciasteczek, na przykład wersja językowa albo waluta w sklepie, jeśli ciasteczko nie wchodzi do klucza [3].
Zagrożenia i skutki
PortSwigger wskazuje dwa czynniki decydujące o wadze ataku: jak szkodliwy jest ładunek, który udało się zapisać, i jaki ruch ma zatruta strona [1]. Jedna zatruta strona główna działa jak Stored XSS, choć sam kod aplikacji niczego nie zapisuje.
- XSS (Cross-Site Scripting) dla wszystkich odwiedzających, w tym zalogowanych administratorów [3];
- ładowanie skryptów z serwera atakującego, a przez nie web skimming w sklepie [3];
- złośliwe przekierowania i podmiana treści strony (defacement);
- zapisanie w pamięci błędnej odpowiedzi, co odcina użytkowników od strony, czyli odmowa usługi (denial of service).
Jak się bronić
PortSwigger zaleca w pierwszej kolejności wyłączenie pamięci podręcznej tam, gdzie to możliwe, albo ograniczenie jej do treści w pełni statycznych [1]. Dalej: wyłączenie obsługi nagłówków, których aplikacja nie potrzebuje, przepisywanie żądań zamiast wyłączania ich części z klucza oraz szybkie łatanie podatności po stronie klienta [1].
Drugą zasadą jest spójność klucza z tym, od czego zależy odpowiedź. Nagłówek Vary opisuje, które części żądania poza metodą i adresem wpłynęły na treść odpowiedzi, i sprawia, że odpowiedzi są zapisywane osobno dla różnych wartości tych nagłówków [5]. Pamięć może użyć zapisanej odpowiedzi tylko wtedy, gdy nagłówki wskazane w Vary zgadzają się z pierwotnym żądaniem [4].
HTTP/1.1 200 OK
Cache-Control: public, max-age=300
Vary: Accept-Encoding, Accept-Language
W praktyce dla WordPressa oznacza to adres witryny ustawiony na stałe w konfiguracji, odrzucanie na serwerze nagłówków przekazujących host od klientów spoza zaufanego proxy, wyłączenie z pamięci podręcznej żądań zalogowanych użytkowników i koszyka oraz czyszczenie pamięci po wykryciu nieprawidłowej treści. WAF może blokować znane wzorce ładunków w nagłówkach, ale nie naprawia źle dobranego klucza.
Historia i przykłady
Badanie z 2018 roku wymieniało wśród podatnych celów między innymi serwisy Red Hat, Unity, Mozilla i data.gov oraz frameworki Drupal, Symfony i Zend [2]. W ramach badania udostępniono rozszerzenie Burp Suite o nazwie Param Miner, które automatycznie wyszukuje nieobjęte kluczem nagłówki i ciasteczka [2]. Obecny standard pamięci podręcznej HTTP, RFC 9111 z czerwca 2022 roku, zastąpił RFC 7234 i ma osobny punkt poświęcony zatruciu pamięci podręcznej [4].
Przypisy
6- [1] Web cache poisoning · PortSwigger Web Security Academy
- [2] Practical Web Cache Poisoning · PortSwigger Research
- [3] Exploiting cache design flaws · PortSwigger Web Security Academy
- [4] RFC 9111: HTTP Caching · IETF
- [5] Vary header · MDN Web Docs
- [6] Cache — Advanced Administration Handbook · WordPress.org