Jak poprawnie wdrożyć nagłówek HSTS?

09 Jan 2020

best-practices  headers  hsts  http  http-strict-transport-security  https  security 

Share on:

Nagłówek HSTS (HTTP Strict Transport Security) jest jednym z najważniejszych nagłówków bezpieczeństwa. Zapobiega on korzystaniu z niezabezpieczonych połączeń HTTP i wymusza użycie protokołu TLS. W tym wpisie omówię ten nagłówek oraz przedstawię zalecaną procedurę jego poprawnej implementacji.

Zasadniczo HSTS (opisany w RFC 6797 [IETF]) pozwala stronom internetowym (aplikacjom) informować przeglądarki, że połączenie powinno być zawsze szyfrowane przez czas zdefiniowany w nagłówku, zapewniając silny poziom bezpieczeństwa twojej web aplikacji.

W dokumencie SSL Labs Grading 2018 określono wykorzystanie nagłówka HSTS jako mocno wskazane. Wykluczenie treści mieszanej, pełne wykorzystanie protokołu HTTPS oraz wykorzystanie nagłówka HSTS z zalecanymi parametrami i wartościami potrafi podbić ogólną ocenę twojej domeny.

Co ciekawe, nagłówek ten jest świetny pod względem poprawy wydajności, ponieważ instruuje przeglądarkę, aby już po stronie klienta przeprowadzała wewnętrzne przekierowanie z HTTP na HTTPS bez dotykania warstwy serwera.

Grafika pochodzi ze świetnego dokumentu What Is HSTS and Why Should I Use It?

Jeżeli chodzi o bezpieczeństwo, to nagłówek HSTS pozwala zapobiec atakom MITM, atakom typu downgrade, a także wysyłaniu plików cookie i identyfikatorów sesji niezaszyfrowanym kanałem. Prawidłowe wdrożenie HSTS to dodatkowy mechanizm bezpieczeństwa zgodny z zasadą bezpieczeństwa wielowarstwowego (ang. defense in depth).

Jedyną obecnie znaną metodą obejścia HSTS jest atak oparty na protokole NTP. Jeśli klient jest podatny na atak NTP, można go oszukać powodując wygaśnięcie zasad HSTS, w celu uzyskania jednorazowego dostępu do witryny za pomocą protokołu HTTP. Polecam dwa świetne dokumenty opisujące ten problem: Bypassing HTTP Strict Transport Security [PDF] oraz Attacking the Network Time Protocol [PDF].

Gdy przeglądarka wie, że domena włączyła HSTS, robi dwie rzeczy:

Nagłówek ten powinien być zawsze ustawiony z parametrem includeSubdomains. Zapewni to solidne bezpieczeństwo zarówno dla głównej domeny, jak i wszystkich subdomen. Problem polega na tym, że bez tego parametru atakujący, który przeprowadza atak man-in-the-middle, może stworzyć dowolne subdomeny i używać ich do wstrzykiwania plików cookie do aplikacji.

Jedną z ważniejszych informacji o tym nagłówku jest to, że wskazuje on, jak długo przeglądarka powinna bezwarunkowo odmawiać udziału w niezabezpieczonym połączeniu HTTP dla określonej domeny.

Co więcej, parametr określający maksymalny czas, przez jaki komunikacja będzie wykorzystywać protokół HTTPS. Zgodnie z zaleceniami, powinien być ustawiony na dużą wartość, np. 31536000 (12 miesięcy) lub 63072000 (24 miesiące). Maksymalny wiek HSTS jest odświeżany za każdym razem, gdy przeglądarka odczytuje nagłówek.

Ciekawostka: HSTS w ogóle nie próbuje obsługiwać zawartości mieszanej, po prostu kontroluje, czy przeglądarka powinna wykonywać wewnętrzne przekierowanie 307 do HTTPS za każdym razem, gdy próbuje załadować adresy po HTTP, czy nie. Ostrzeżenie o mieszanej zawartości we wszystkich wymienionych przeglądarkach jest sprawdzane przed załadowaniem jakiejkolwiek treści, w tym odczytaniu nagłówka HSTS.

Jeżeli chcemy ustawić ten nagłówek z poziomu serwera NGINX, należy pamiętać o ustawieniu go w bloku http z opcją ssl dla danej konfiguracji nasłuchiwania — w przeciwnym razie ryzykujesz wysłanie nagłówka Strict-Transport-Security przez połączenie HTTP, które również mogłeś skonfigurować w innym bloku konfiguracji. Dodatkowo powinieneś użyć przekierowania 301 za pomocą return 301, aby blok serwera HTTP został przekierowany do HTTPS.

Oto zalecana konfiguracja nagłówka HSTS w przypadku serwera NGINX (31536000 = 1 rok, 63072000 = 2 lata):

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains" always;

Czy HSTS ma jakieś minusy? #

Tak. Niestety przy pierwszym wejściu na stronę nie jesteś chroniony przez HSTS. Jeśli witryna dodaje nagłówek HSTS do połączenia HTTP, nagłówek ten jest ignorowany. Jest tak, ponieważ atakujący może usunąć lub dodać nagłówki podczas ataku man-in-the-middle. Nie można ufać nagłówkowi HSTS, chyba że zostanie dostarczony przez HTTPS.

W celu zminimalizowania tego problemu HSTS dostarcza tzw. listę wstępnego ładowania. Jest to lista dystrybuowana wraz z przeglądarkami (prowadzona przez projekt Chromium, jednak nie jest oficjalnie częścią standardu), zawierająca serwisy korzystające z protokołu HSTS. Jeżeli dodasz swoją witrynę do tej listy, przeglądarka najpierw sprawdzi, czy serwis widnieje na liście, jeśli tak, dostęp do twojej strony nigdy nie będzie możliwy przez protokół HTTP, nawet podczas pierwszej próby połączenia.

Ponadto, jeśli chodzi o parametr includeSubdomains, jego skutkiem ubocznym jest oczywiście to, że będziesz musiał wdrożyć TLS dla wszystkich subdomen (jednak obecnie powinno to być standardem!).

Na co uważać przy wdrażaniu nagłówka HSTS? #

Wdrożenie nagłówka HSTS powinno być obowiązkowym krokiem, jednak musi zostać zrobione z głową. Niestety wiele artykułów pomija dobre praktyki związane z przeprowadzeniem jego prawidłowej implementacji i skupia się na samych zaleceniach jego włączenia, podając tylko parametry i ich wartości.

Myślę, że najlepszym how-to jak to zrobić są zalecenia firmy Qualys opisane w dokumencie The Importance of a Proper HTTP Strict Transport Security Implementation on Your Web Server. Jest to świetne wyjaśnienie, dlatego pozwolę sobie je zacytować w oryginalnej formie:

Nieprzemyślane włączenie tego nagłówka utrudnia znacznie strategię jego wycofywania. Dlatego przed wdrożeniem koniecznie zapoznaj się z zaleceniami firmy Google, która definiuje reguły włączenie HSTS:

Myślę, że rozsądnie jest także przyjąć następujące kroki:

Na każdym etapie sprawdzaj, czy po wejściu na stronę nie zwraca ona żadnych błędów. Pamiętaj także o monitorowaniu ruchu i wpływu wprowadzonych zmian na wyszukiwarki, roboty oraz innych klientów. Jeżeli pojawią się jakiekolwiek problemy na danym etapie, zlokalizuj problem i go napraw, a następnie poczekaj ponownie pełen maksymalny czas etapu, zanim przejdziesz dalej.

Jeżeli weryfikacja ostatniego etapu (tj. odczekanie pełnego miesiąca) przejdzie pomyślnie, zwiększ maksymalny wiek do 12 lub 24 miesięcy i dodaj swoją witrynę na listę wstępnego ładowania, pamiętając o odpowiednim ustawieniu nagłówka:

max-age=63072000; includeSubDomains; preload

Pamiętaj, że 1 rok jest minimalny, aby domena mogła zostać uwzględniona na listach wstępnego ładowania HSTS przeglądarki. Jednak zalecaną wartością jest okres 2 lat.

Na zakończenie polecam przeczytać: