Serwer WebSocket niemal zawsze mówi również w HTTP: serwuje stronę, która otwiera gniazdo, odpowiada na kontrole stanu, hostuje API albo przekierowuje do Twojego front-endu. Ta powierzchnia HTTP ma własne dobrze znane klasy ataków, a najnowszy sgcWebSockets domyślnie zamyka te najważniejsze. Dotyczy to obu serwerów HTTP: opartego na Indy TsgcWebSocketHTTPServer oraz opartego na windowsowym http.sys TsgcWebSocketServer_HTTPAPI.
Path traversal jest zablokowany
Jeśli serwujesz pliki statyczne, ustawiając DocumentRoot, serwer dawniej budował ścieżkę pliku przez połączenie katalogu głównego dokumentów ze ścieżką żądania. Żądanie takie jak GET /../../../../windows/win.ini lub jego forma zakodowana w URL /..%2f..%2f... mogło wyjść poza katalog główny serwisu i odczytać dowolne pliki. Serwer teraz kanonizuje rozwiązaną ścieżkę i serwuje ją tylko wtedy, gdy pozostaje wewnątrz DocumentRoot; wszystko, co z niego ucieka, jest odrzucane. Działa to zawsze, zarówno na ścieżkach HTTP/1.x, jak i HTTP/2, i nie wymaga żadnej konfiguracji.
Ograniczanie ciała żądania
Ciało żądania HTTP nie ma wbudowanego limitu rozmiaru, więc klient mógł zadeklarować ogromne Content-Length i przesłać strumieniowo gigabajty danych, aby wyczerpać pamięć serwera. Nowa właściwość MaxRequestBodySize ją ogranicza. Domyślnie wynosi 64 MB, a żądanie deklarujące więcej jest odrzucane z kodem 413, zanim ciało zostanie zbuforowane. Zwiększ ją dla dużych przesyłek lub ustaw na 0, aby wyłączyć limit.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 80;
oServer.MaxRequestBodySize := 16 * 1024 * 1024; // 16 MB, reject larger with 413
oServer.Active := True;
Bardziej rygorystyczne parsowanie żądań zatrzymuje smuggling
HTTP request smuggling wykorzystuje serwery, które nie zgadzają się co do tego, gdzie kończy się jedno żądanie, a zaczyna następne, zwykle przez wysłanie zarówno nagłówka Content-Length, jak i Transfer-Encoding: chunked. Nowa właściwość StrictRequestParsing, włączona domyślnie, odrzuca takie dwuznaczne żądania z kodem 400 i stosuje bardziej rygorystyczną walidację kodowania chunked, dzięki czemu serwer proxy front-endu i serwer nie mogą się rozsynchronizować.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.StrictRequestParsing := True; // default: reject Content-Length + Transfer-Encoding
oServer.MaxRequestBodySize := 64 * 1024 * 1024;
oServer.Active := True;
Obrona przed HTTP/2 Rapid Reset
Atak HTTP/2 Rapid Reset (CVE-2023-44487) otwiera strumień i natychmiast go anuluje za pomocą RST_STREAM, w ciasnej pętli, zmuszając serwer do wykonywania nieograniczonej pracy nad żądaniami niemal bez kosztu po stronie klienta. Serwer HTTP/2 ogranicza teraz, ile resetów i ramek kontrolnych może wysłać pojedyncze połączenie, dostarcza skończoną wartość domyślną 100 jednoczesnych strumieni i zamyka nadużywające połączenie ramką GOAWAY. HTTP/2 jest opcjonalny, więc ma to znaczenie tylko wtedy, gdy go włączyłeś, ale jeśli to zrobiłeś, obrona jest automatyczna.
Czystsze nagłówki odpowiedzi
Gdy aplikacja buduje nagłówek odpowiedzi z danych zależnych od żądania, na przykład cel przekierowania lub znacznik encji, znak powrotu karetki lub przejścia do nowej linii przemycony do tej wartości mógł rozdzielić odpowiedź i wstrzyknąć dodatkowe nagłówki. Serwer http.sys usuwa teraz CR i LF z wartości nagłówków odpowiedzi, takich jak Location, Server i ETag, więc pojedyncza wartość nie może już stać się dwoma nagłówkami.
Gdzie wpisuje się zapora sieciowa
Te zabezpieczenia znajdują się we własnym parserze HTTP i serwerze plików serwera, czyli w warstwie, której komponenty Firewall i RateLimiter nie są w stanie objąć. Nadal używaj zapory do filtrowania adresów IP, ograniczania liczby żądań i polityki pochodzenia, a wbudowane mechanizmy obronne niech strzegą parsowania i serwowania plików statycznych. W przypadku serwera publicznego zalecamy również ustawianie DocumentRoot tylko wtedy, gdy faktycznie serwujesz pliki, dostrojenie MaxRequestBodySize do Twojego rzeczywistego maksimum oraz ograniczenie MaxConnections.
Aktualizacja
Nowe zabezpieczenia są aktywne, gdy tylko zaktualizujesz, z bezpiecznymi ustawieniami domyślnymi, więc większość serwerów zyskuje to wzmocnienie bez zmian w kodzie. Jeśli Twoja aplikacja przyjmuje ciała żądań większe niż 64 MB, odpowiednio zwiększ MaxRequestBodySize. Istniejący klienci nie są dotknięci zmianami.
Zaktualizuj ze strony pobierania sgcWebSockets lub pobierz przez GetIt albo swoje zarejestrowane konto.
Pytania, opinie lub pomoc w migracji? Skontaktuj się z nami, otrzymasz odpowiedź od osób, które napisały ten kod.
