DeepSeek Harness pozwalał atakującemu w piaskownicy na uruchamianie dowolnych poleceń poprzez samą zmianę nagłówka HTTP Host na 127.0.0.1, co skutkuje oceną 9.4 w skali CVSS. Ta luka pokazuje, jak pojedyncza, błędna decyzja o zaufaniu może zmienić barierę ochronną w otwarte tylne wejście (backdoor).
Jak doszło do błędu
Podatny kod znajduje się w pojedynczej funkcji, która odczytuje nagłówek Host zapytania i, jeśli jego wartość jest równa adresowi pętli zwrotnej (loopback), traktuje zapytanie jako pochodzące z lokalnej maszyny.
Atakujący, który może wykonywać kod wewnątrz piaskownicy, nie potrzebuje wyrafinowanego ładunku (payload). Wysyłając jedno zapytanie HTTP z Host: 127.0.0.1, backend uznaje, że wywołanie pochodzi z samego hosta i pomija wszystkie monity bezpieczeństwa, sprawdzanie limitów prędkości (rate-limiting) oraz kroki walidacji poleceń. Wynik: nieograniczone wykonywanie poleceń bez konieczności dalszej interakcji.
Dlaczego ufanie nagłówkom jest niebezpieczne
Nagłówki to ciągi znaków tekstowych dostarczane przez klienta. Niezależnie od tego, czy pole nazywa się Host, X-Forwarded-For, czy ma dowolną inną nazwę, klient może ustawić je na dowolną wartość. Jedynym wiarygodnym źródłem informacji o tym, skąd naprawdę pochodzi połączenie, jest warstwa transportowa – adres IP źródłowy gniazda (socket), który system operacyjny rejestruje po zakończeniu uścisku dłoni TCP (TCP handshake).
Gdy aplikacja decyduje się zaufać nagłówkowi bez potwierdzenia, że został on wstrzyknięty przez znany i poprawnie skonfigurowany serwer proxy, przekazuje atakującemu klucze do królestwa. Błąd w DeepSeek Harness jest podręcznikowym przykładem takiego potknięcia.
Wpływ w świecie rzeczywistym: przykład shell.online
Projekt open-source shell.online, oferujący terminal w przeglądarce, niedawno udokumentował tę samą pułapkę. Wykorzystuje on flagę konfiguracyjną o nazwie TRUST_PROXY:
- TRUST_PROXY = 0 – aplikacja ignoruje nagłówek X-Forwarded-For i polega na zdalnym adresie gniazda. Zapobiega to podszywaniu się klienta pod inny adres IP w celu obejścia limitów prędkości lub udawania zaufanego użytkownika.
- TRUST_PROXY = 1 – aplikacja ufa nagłówkowi X-Forwarded-For jako tożsamości klienta. Jeśli usługa nie znajduje się za rzeczywistym serwerem proxy, który oczyszcza (sanitises) ten nagłówek, atakujący może podawać nowy adres IP przy każdym zapytaniu, skutecznie resetując wszelkie ograniczanie przepustowości (throttling) na pojedyncze IP.
Błąd w DeepSeek odzwierciedla ten scenariusz: kod ufał nagłówkowi Host, jakby został on ustawiony przez proxy, mimo że do usługi można było uzyskać bezpośredni dostęp.
Co programiści powinni zrobić teraz
- Przejrzyj każde miejsce, w którym odczytujesz nagłówki dostarczane przez klienta. Zidentyfikuj nagłówki, które traktujesz jako wiarygodne (np. Host, X-Forwarded-For, X-Real-IP) i upewnij się, że zaufany serwer proxy na pewno je nadpisze, zanim dotrą do Twojej aplikacji.
- W miarę możliwości powiąż decyzje dotyczące bezpieczeństwa z adresem gniazda. Używaj adresu IP źródłowego dostarczanego przez system operacyjny do uwierzytelniania, ograniczania prędkości (rate-limiting) i sprawdzania kontroli dostępu.
- Włączaj flagi zaufania do proxy tylko wtedy, gdy przed usługą znajduje się poprawnie skonfigurowany reverse proxy. Jeśli uruchamiasz aplikację bezpośrednio, pozostaw te flagi wyłączone.
- Dokumentuj wymaganą topologię wdrożenia w pliku README lub przewodniku wdrożeniowym projektu, aby użytkownicy korzystający z własnych serwerów (self-hosting) wiedzieli o wymogu zaufania do proxy.
- Używaj narzędzi do analizy statycznej lub przeglądu kodu, które flagują bezpośrednie wykorzystywanie nagłówków do podejmowania decyzji o bezpieczeństwie bez towarzyszącej im logiki walidacji proxy.
Na co zwrócić uwagę w przyszłości
Społeczności dostarczające usługi webowe do samodzielnego hostowania prawdopodobnie ponownie zweryfikują własne ustawienia zaufania do proxy po tym incydencie.
Główna lekcja jest jednoznaczna: nigdy nie pozwól, aby fragment tekstu, który każdy w internecie może napisać, dyktował poziom bezpieczeństwa Twojego systemu. Ufaj warstwie sieciowej, a nie warstwie zapytania.
