Guides 6 min czytania

Nagłówki bezpieczeństwa HTTP: co wysyłać i jak je sprawdzić

HSTS, Content-Security-Policy, X-Content-Type-Options, ochrona przed osadzaniem w ramkach, Referrer-Policy i Permissions-Policy: co robi każdy z nich i od jakiej bezpiecznej wartości zacząć.

Nagłówki bezpieczeństwa HTTP to nagłówki odpowiedzi, które każą przeglądarce zastosować zabezpieczenia, jakie w przeciwnym razie Twoja strona musiałaby zbudować sama: pozostań przy HTTPS, uruchamiaj tylko skrypty z zaufanych źródeł, nie zgaduj typów plików, nie pozwalaj innym stronom osadzać tej strony w ramce i zdradzaj mniej o tym, skąd przyszedł odwiedzający. Większość zapewnia sześć nagłówków: Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options (lub dyrektywa CSP frame-ancestors), Referrer-Policy i Permissions-Policy. Większość z nich to jedna linia w konfiguracji serwera. Content-Security-Policy wymaga planowania, więc zacznij od trybu Report-Only.

Sześć nagłówków w skrócie

NagłówekChroni przedWartość na początekStrict-Transport-SecurityObniżeniem połączenia do zwykłego HTTPmax-age=31536000Content-Security-PolicyWstrzykniętymi skryptami (cross-site scripting)Polityka najpierw przetestowana w trybie Report-OnlyX-Content-Type-OptionsUruchamianiem pliku przez przeglądarkę jako innego typunosniffX-Frame-Options lub frame-ancestorsClickjackingiem przez ramkiSAMEORIGIN i frame-ancestors 'self’Referrer-PolicyWyciekiem pełnych adresów do innych stronstrict-origin-when-cross-originPermissions-PolicyŻądaniami dostępu do nieużywanych funkcji przeglądarkicamera=(), microphone=(), geolocation=()

Strict-Transport-Security (HSTS)

Nawet z przekierowaniem z HTTP na HTTPS odwiedzający, który wpisuje Twoją domenę, wysyła pierwsze żądanie przez zwykłe HTTP, gdzie po drodze można je odczytać lub zmienić. HSTS każe przeglądarce od tej pory łączyć się z Twoją domeną przez HTTPS, przez czas podany w max-age, w sekundach:

Strict-Transport-Security: max-age=31536000

Zacznij od krótkiego czasu. Przeglądarki stosują HSTS aż do jego wygaśnięcia, więc błąd zostaje na długo. Spróbuj max-age=300 przez kilka dni, a potem zwiększ do roku (31536000).

includeSubDomains stosuje regułę do każdej subdomeny. Dodaj ją tylko wtedy, gdy wszystkie, łącznie ze starymi hostami testowymi i pocztowymi, działają przez HTTPS.

preload to prośba o wbudowanie domeny w przeglądarki przez hstspreload.org, co wymaga max-age wynoszącego co najmniej rok oraz includeSubDomains. Usunięcie trwa długo, więc traktuj to jako decyzję na stałe.

Przeglądarki ignorują HSTS w odpowiedziach przez zwykłe HTTP. Wysyłaj go przez HTTPS i pilnuj certyfikatu: przy HSTS wygasłego certyfikatu nie da się kliknięciem pominąć.

Content-Security-Policy

Content Security Policy określa, skąd strona może ładować skrypty, style, obrazy, czcionki i ramki oraz dokąd mogą być wysyłane formularze. Jeśli atakujący zdoła umieścić skrypt na stronie, przez pole komentarza albo przejętą wtyczkę, przeglądarka odmówi jego uruchomienia, chyba że polityka dopuszcza jego źródło. To najskuteczniejszy z sześciu nagłówków i zarazem najłatwiej go źle ustawić, bo zbyt restrykcyjna polityka psuje Twoją analitykę, widżet czatu czy formularz płatności.

Zacznij od trybu Report-Only

Najpierw wysyłaj politykę jako Content-Security-Policy-Report-Only. Przeglądarka niczego nie blokuje, ale zgłasza każde naruszenie na adres podany w report-uri (lub nowszym report-to) i zapisuje je w konsoli. Punkt wyjścia dla strony, która serwuje własne pliki:

Content-Security-Policy-Report-Only: default-src 'self’; script-src 'self’; style-src 'self’; img-src 'self’ data:; font-src 'self’; object-src 'none’; base-uri 'self’; form-action 'self’; frame-ancestors 'self’; report-uri /csp-report

Przejrzyj stronę, zbieraj raporty przez tydzień lub dwa i dodaj źródła, z których naprawdę korzystasz, np. dostawcę analityki czy płatności. Gdy raporty pokazują już tylko to, co chcesz blokować, wysyłaj tę samą politykę jako Content-Security-Policy.

Skrypty inline: nonce zamiast unsafe-inline

Restrykcyjna polityka blokuje bloki <script> inline i atrybuty onclick, bo wstrzyknięty skrypt wygląda tak samo. Dodanie 'unsafe-inline’ usuwa problem, ale razem z nim większość ochrony. Zamiast tego nadaj każdej odpowiedzi losowy nonce, wpisz go do polityki jako 'nonce-…’ i umieść tę samą wartość we własnych znacznikach script; obsługę zdarzeń inline przenieś do plików ze skryptami. Menedżery tagów, które wstrzykują własne skrypty, wymagają szczególnej uwagi, bo każdy dodawany przez nie tag także musi być dozwolony.

X-Content-Type-Options

Przeglądarki zgadywały kiedyś typ pliku na podstawie jego zawartości, gdy Content-Type wysłany przez serwer wyglądał na błędny. Dzięki temu przesłany „obrazek” mógł zostać uruchomiony jako skrypt. X-Content-Type-Options: nosniff wyłącza to zgadywanie. Nagłówek ma jedną poprawną wartość i nie ma znanych wad, o ile serwer wysyła prawidłowe typy treści, więc wysyłaj go w każdej odpowiedzi.

X-Frame-Options i frame-ancestors

W ataku typu clickjacking inna strona wyświetla Twoją stronę w niewidocznej ramce i nakłania odwiedzających do klikania w jej przyciski. X-Frame-Options: DENY blokuje każde osadzanie w ramce, a SAMEORIGIN dopuszcza tylko Twoje własne strony. Dyrektywa CSP frame-ancestors robi to samo, dając więcej kontroli, np. listę stron partnerów, i ma pierwszeństwo w przeglądarkach, które ją obsługują. Wysyłaj oba: frame-ancestors dla obecnych przeglądarek, X-Frame-Options dla starszych. Dawna wartość ALLOW-FROM nie jest już obsługiwana, więc do wszystkiego poza własnym originem używaj frame-ancestors.

Referrer-Policy

Gdy odwiedzający kliknie link, przeglądarka przekazuje kolejnej stronie w nagłówku Referer, skąd przyszedł. Bez ograniczeń może to być pełny adres, łącznie z zapytaniem wyszukiwania, tokenem resetu hasła czy numerem zamówienia w URL. strict-origin-when-cross-origin wysyła pełny adres w obrębie Twojej strony, do innych stron tylko domenę, a przy przejściu z HTTPS na HTTP nic. Tak zachowują się obecne przeglądarki, gdy nagłówka brakuje, ale jego wysłanie czyni ten wybór jawnym. Na stronach z prywatnymi danymi w adresach URL używaj no-referrer i unikaj unsafe-url, który wysyła wszystko wszędzie.

Permissions-Policy

Permissions-Policy, dawniej Feature-Policy, wyłącza funkcje przeglądarki, z których Twoja strona nie korzysta, zarówno dla samej strony, jak i dla każdej osadzonej w niej ramki. Pusta lista, (), oznacza, że nikt nie może używać danej funkcji:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()

Pomiń funkcje, których używasz, albo zezwól na nie dla własnego originu za pomocą (self), np. payment=(self) w sklepie z przyciskiem płatności.

Nagłówki, które możesz pominąć

X-XSS-Protection sterował filtrem, który obecne przeglądarki usunęły. Pomiń go albo wysyłaj 0.

Expect-CT i Public-Key-Pins są przestarzałe. Przypinanie kluczy mogło odciąć odwiedzającym dostęp do strony i dlatego przeglądarki z niego zrezygnowały.

Server i X-Powered-By nie są nagłówkami bezpieczeństwa, ale dokładne numery wersji w nich pomagają atakującym dobrać exploit. Skróć je tam, gdzie pozwala na to serwer.

Gdzie je ustawić

Ustawiaj nagłówki w jednym miejscu, jak najbliżej krawędzi: na serwerze WWW, w CDN lub w middleware aplikacji. W nginx i Apache:

# nginx (in the server block)
add_header Strict-Transport-Security „max-age=31536000” always;
add_header X-Content-Type-Options „nosniff” always;
add_header X-Frame-Options „SAMEORIGIN” always;
add_header Referrer-Policy „strict-origin-when-cross-origin” always;
add_header Permissions-Policy „camera=(), microphone=(), geolocation=()” always;

# Apache (.htaccess or virtual host, with mod_headers)
Header always set X-Content-Type-Options „nosniff”
Header always set Referrer-Policy „strict-origin-when-cross-origin”

Dwa szczegóły nginx często zaskakują. Bez always nagłówki są dodawane tylko do udanych odpowiedzi, a nie do stron błędów. A blok location z jakąkolwiek własną dyrektywą add_header pomija wszystkie nagłówki z bloku server, więc jeden nagłówek cache dla obrazków może tam po cichu usunąć Twoje nagłówki bezpieczeństwa. Uważaj też na ten sam nagłówek ustawiony dwukrotnie, przez serwer i przez aplikację lub CDN: przeglądarki różnie traktują duplikaty w zależności od nagłówka, więc wyznacz dla każdego jednego właściciela.

Jak sprawdzić swoje nagłówki

W terminalu curl -sI https://example.com wypisuje nagłówki odpowiedzi. Sprawdź też końcowy adres po przekierowaniach, stronę błędu i plik statyczny, bo każdy z nich może być serwowany przez inną część Twojej infrastruktury. W przeglądarce karta Sieć w narzędziach deweloperskich pokazuje nagłówki każdego żądania, a konsola pokazuje naruszenia CSP.

Możesz też skorzystać z naszego darmowego narzędzia do sprawdzania nagłówków HTTP. Wyświetla każdy nagłówek wysyłany przez URL po przejściu przekierowań, zaznacza, których z sześciu nagłówków bezpieczeństwa brakuje, wskazuje kilka wartości, które je niweczą, takich jak krótki max-age w HSTS, CSP działająca tylko w trybie Report-Only czy unsafe-url, oraz pokazuje, jak strona jest cache’owana i na co schodzi czas. Sprawdza, czy nagłówki są obecne; nie ocenia, na co pozwala Content Security Policy, więc to przejrzyj samodzielnie.

Nie pozwól im zniknąć

Nagłówki bezpieczeństwa rzadko psują się z hukiem. Znikają, gdy strona przenosi się na nowy serwer, zmienia się CDN, aktualizuje się wtyczka albo ktoś dodaje blok location, a strona dalej działa, więc nikt tego nie zauważa. Monitor HTTP w ramach monitorowania dostępności Uptimecheck może sprawdzać nagłówki odpowiedzi przy każdym żądaniu, do 10 sprawdzeń odpowiedzi na monitor, na przykład:

Strict-Transport-Security istnieje.

X-Content-Type-Options ma wartość nosniff.

Content-Security-Policy zawiera frame-ancestors.

Każde sprawdzenie musi być spełnione, by monitor był uznany za działający, więc brak nagłówka oznacza awarię, drugi test ją potwierdza, a Ty dostajesz alert. Jeśli nie chcesz, by sprawdzenia nagłówków wpływały na dostępność strony, umieść je w osobnym monitorze. Testy mogą odbywać się nawet co minutę ze Sztokholmu, Londynu i Nowego Jorku; zobacz, jak monitorować endpoint API, by skonfigurować sprawdzanie odpowiedzi, oraz listę kontrolną utrzymania strony, by poznać resztę rutyny.

Dowiedz się tego samego dnia, gdy nagłówek zniknie. Wypróbuj Uptimecheck za darmo przez 14 dni, bez karty kredytowej.

Pytania

Jakie nagłówki bezpieczeństwa HTTP powinna wysyłać każda strona?

Strict-Transport-Security, X-Content-Type-Options: nosniff, X-Frame-Options lub dyrektywę CSP frame-ancestors, Referrer-Policy i Permissions-Policy łatwo dodać. Content-Security-Policy daje największą ochronę, ale najpierw wymaga przetestowania w trybie Report-Only.

Czym jest Content-Security-Policy-Report-Only?

To ta sama polityka co Content-Security-Policy, ale przeglądarka tylko zgłasza, co by zablokowała, zamiast to blokować. Użyj jej, by znaleźć źródła, których Twoja strona naprawdę potrzebuje, zanim zaczniesz egzekwować politykę.

Czy nadal potrzebuję X-Frame-Options, jeśli używam frame-ancestors?

Obecne przeglądarki stosują frame-ancestors i ignorują X-Frame-Options, gdy oba są obecne. Wysyłanie obu nic nie kosztuje i chroni odwiedzających korzystających ze starszych przeglądarek.

Czy X-XSS-Protection jest nadal potrzebny?

Nie. Filtr, którym sterował, został usunięty z obecnych przeglądarek. Pomiń ten nagłówek albo wysyłaj 0 i polegaj zamiast tego na Content Security Policy.

Czytaj dalej

Guides 6 min czytania

Budżet błędów: czym jest i jak z niego korzystać

Jak obliczyć budżet błędów na podstawie SLO, co go zużywa, jak działa burn rate i jak napisać politykę budżetu błędów, której Twój zespół naprawdę będzie przestrzegać.

Czytaj

Przestoje to przeszłość.

Skonfiguruj pierwszy monitor w niecałą minutę albo najpierw rozejrzyj się w demo na żywo.

14 dni za darmo · Potem 5 monitorów gratis · Bez karty kredytowej