Nagłówki bezpieczeństwa strony: HSTS, CSP i reszta bez żargonu
Nagłówki bezpieczeństwa to krótkie polecenia, które serwer wysyła przeglądarce razem ze stroną, na przykład „łącz się ze mną tylko przez HTTPS” (HSTS) albo „nie pokazuj mnie w ramce na cudzej stronie” (X-Frame-Options lub CSP frame-ancestors). Ustawia się je raz dla całej domeny w konfiguracji serwera, w panelu hostingu albo w Cloudflare, a sprawdzisz je sam w narzędziach deweloperskich przeglądarki.
- Nagłówek Strict-Transport-Security (HSTS) każe przeglądarce przez czas podany w max-age łączyć się z domeną wyłącznie przez HTTPS; 31536000 sekund to rok.
- Serwis hstspreload.org, który prowadzi listę domen wbudowaną w przeglądarki, zaleca sam nagłówek HSTS, a wpisywanie domeny na listę nazywa niezalecanym, bo jej usunięcie trwa miesiące.
- Według MDN dyrektywa frame-ancestors w nagłówku Content-Security-Policy daje więcej możliwości niż starszy nagłówek X-Frame-Options, a wartość ALLOW-FROM jest przestarzała i przeglądarki ignorują wtedy cały nagłówek.
- Gdy strona nie wysyła nagłówka Referrer-Policy, przeglądarki stosują domyślnie zasadę strict-origin-when-cross-origin, więc ten nagłówek głównie potwierdza albo zaostrza ustawienie domyślne.
Czym są nagłówki bezpieczeństwa i po co Ci one
Gdy ktoś otwiera Twoją stronę, serwer odsyła nie tylko treść, ale też kilkanaście krótkich linijek technicznych, czyli nagłówków HTTP. Klient ich nie widzi. Część z nich to polecenia dla przeglądarki: czy połączenie ma być zawsze szyfrowane, z jakich adresów wolno ładować skrypty i czy stronę można pokazać w ramce na innej witrynie.
Nagłówki nie naprawią dziurawej wtyczki ani słabego hasła do panelu. Ograniczają za to skutki typowych ataków. Chodzi o podsłuch połączenia w publicznym Wi-Fi, o clickjacking, czyli osadzenie Twojej strony w niewidocznej ramce, żeby ktoś kliknął coś za klienta, i o XSS, czyli uruchomienie obcego skryptu wstrzykniętego przez lukę na stronie.
To tania ochrona, bo ustawia się ją raz dla wszystkich podstron. Sprawdzają ją też bezpłatne narzędzia, na przykład HTTP Observatory od Mozilli, którymi działy IT klientów oceniają dostawców.
Sześć nagłówków, które warto mieć
Wartości w trzeciej kolumnie to bezpieczny początek, a nie jedyna słuszna konfiguracja.
Do tego dochodzi zasada odwrotna: nie wysyłaj informacji, które pomagają atakującym. Nagłówki w rodzaju X-Powered-By: PHP/8.1.2 albo Server: Apache/2.4.41 podają dokładną wersję oprogramowania. Automatyczne skanery szukają w sieci właśnie stron ze starymi wersjami, więc te nagłówki lepiej ukryć albo skrócić do samej nazwy serwera.
| Nagłówek | Co robi | Wartość na start |
|---|---|---|
| Strict-Transport-Security (HSTS) | Przeglądarka przez podany czas łączy się tylko przez HTTPS, nawet gdy ktoś wpisze http:// | max-age=31536000; includeSubDomains |
| Content-Security-Policy (CSP) | Lista źródeł, z których wolno ładować skrypty, style, obrazy i ramki | Zależna od strony; najpierw w trybie testowym Report-Only |
| X-Frame-Options albo CSP frame-ancestors | Blokuje pokazywanie strony w ramce na cudzej witrynie | SAMEORIGIN albo frame-ancestors 'self' |
| X-Content-Type-Options | Przeglądarka nie zgaduje typu pliku; skrypt albo styl o złym typie zostaje zablokowany | nosniff |
| Referrer-Policy | Ogranicza, jaka część adresu Twojej podstrony trafia do innych serwisów po kliknięciu linku | strict-origin-when-cross-origin |
| Permissions-Policy | Wyłącza funkcje przeglądarki, których strona nie używa, na przykład kamerę i mikrofon | camera=(), microphone=(), geolocation=() |
HSTS: jak włączyć szyfrowanie na stałe bez ryzyka
HSTS opisuje standard RFC 6797. Po pierwszej wizycie przeglądarka zapamiętuje, że Twoja domena działa tylko przez HTTPS, i przez czas z parametru max-age sama zamienia http:// na https://. Dzięki temu nikt w sieci kawiarni nie przechwyci nieszyfrowanego połączenia i nie podsunie klientowi fałszywej wersji strony.
Dopisek includeSubDomains obejmuje też subdomeny. Stary panel pod http://panel.twojadomena.pl bez certyfikatu przestanie się wtedy otwierać, dlatego kolejność kroków jest ważna.
Dopisek preload i zgłoszenie domeny na hstspreload.org wpisują ją na listę wbudowaną w przeglądarki. Sam serwis pisze, że zyski z tej listy są małe w porównaniu z samym nagłówkiem, a usunięcie domeny trwa miesiące. Małej firmie zwykle wystarczy nagłówek bez zgłoszenia.
- Sprawdź, że strona główna, wszystkie podstrony i używane subdomeny otwierają się po https:// bez ostrzeżeń.
- Ustaw najpierw krótki czas, na przykład
max-age=300, czyli 5 minut. - Po kilku dniach bez problemów wydłuż czas do 31536000 sekund, czyli roku, i dopisz includeSubDomains.
CSP: najmocniejszy nagłówek, który wymaga testów
Content-Security-Policy to lista zaufanych źródeł. Mówi przeglądarce na przykład: skrypty tylko z mojej domeny i z serwera analityki, ramki tylko z YouTube. Jeśli ktoś przez lukę w formularzu wstrzyknie na stronę obcy skrypt, przeglądarka go nie uruchomi. Web.dev podkreśla, że CSP to dodatkowa warstwa obrony, a nie zamiennik dbania o bezpieczny kod.
Źle ustawiona CSP potrafi wyłączyć czat, mapę, formularz albo statystyki. Dlatego zaczyna się od nagłówka Content-Security-Policy-Report-Only. W tym trybie przeglądarka niczego nie blokuje, tylko zgłasza w konsoli, co by zablokowała. Po tygodniu albo dwóch widać, które źródła są potrzebne, i można włączyć właściwy nagłówek.
Web.dev zaleca ścisłą CSP, opartą na nonce, czyli jednorazowej losowej wartości przy każdym zaufanym skrypcie, albo na skrótach (hash) skryptów. Jest trudniejsza do obejścia niż lista domen, ale wymaga zmian w kodzie. Na prostej stronie lista domen też jest dużym krokiem naprzód.
Gdzie się to ustawia
Nagłówki dodaje się po stronie serwera: na Apache w pliku .htaccess, na nginx w jego konfiguracji, a na Cloudflare regułą zmieniającą nagłówki odpowiedzi. CSP i Referrer-Policy da się też wpisać znacznikiem <meta> w sekcji <head>, ale dyrektywa frame-ancestors działa tylko w nagłówku, a HSTS, X-Frame-Options, nosniff i Permissions-Policy przeglądarka czyta wyłącznie z nagłówków serwera.
Ochrona przed ramką ma dwa zapisy: starszy X-Frame-Options z wartością DENY albo SAMEORIGIN i nowszy frame-ancestors w CSP, który pozwala wskazać zaufane domeny. Wystarczy jeden.
Cookies sesji, czyli pliki, dzięki którym klient pozostaje zalogowany w panelu albo sklepie, powinny mieć flagę HttpOnly. Wtedy skrypt na stronie nie może ich odczytać, więc nawet udany XSS nie przejmie sesji. W PHP włącza to ustawienie session.cookie_httponly.
Jak sprawdzić to samemu
- Otwórz stronę w Chrome albo Firefoksie, naciśnij F12, przejdź do zakładki Sieć (Network), odśwież stronę i kliknij pierwszy wiersz z adresem strony. W sekcji nagłówków odpowiedzi (Response Headers) poszukaj strict-transport-security, content-security-policy, x-frame-options, x-content-type-options i referrer-policy.
- W tym samym miejscu sprawdź nagłówki server i x-powered-by. Jeśli widać numer wersji, poproś hosting o jego ukrycie.
- Wpisz adres strony w bezpłatnym HTTP Observatory od Mozilli (https://developer.mozilla.org/en-US/observatory). Dostaniesz ocenę i listę brakujących nagłówków z opisem.
- Na stronie https w zakładce Konsola (Console) poszukaj ostrzeżeń o mixed content, czyli plikach ładowanych przez zwykłe http://.
Co sprawdza bezpłatny skan
- Czy strona główna działa przez HTTPS.
- Czy odpowiedź strony głównej zawiera nagłówki Strict-Transport-Security i
X-Content-Type-Options: nosnifforaz politykę Content-Security-Policy. CSP przyjmujemy z nagłówka albo ze znacznika<meta http-equiv="Content-Security-Policy">w sekcji<head>. Znacznik liczy się wtedy, gdy coś ogranicza: samo upgrade-insecure-requests nie wystarczy. Przy HSTS i CSP sprawdzamy obecność, a nie ocenę każdej wartości. - Czy strona jest chroniona przed osadzeniem w ramce: nagłówkiem X-Frame-Options albo dyrektywą frame-ancestors w nagłówku CSP. Dyrektywa frame-ancestors w znaczniku
<meta>nie chroni, bo przeglądarki czytają ją tylko z nagłówka. - Czy strona ustawia Referrer-Policy nagłówkiem albo znacznikiem
<meta name="referrer">. Brak to tylko wskazówka, bo obecne przeglądarki same stosują zasadę strict-origin-when-cross-origin. Permissions-Policy odnotowujemy, ale jego brak nie obniża wyniku. - Czy serwer wysyła nagłówek X-Powered-By, który zdradza technologię, np. PHP/8.1.2 albo Next.js, albo nagłówek Server z numerem wersji Apache, nginx, PHP lub IIS.
- Czy strona https ładuje obrazy, skrypty, style albo ramki przez zwykłe http:// (mixed content) oraz czy cookies sesji, na przykład PHPSESSID, mają flagę HttpOnly.
- Czy linki z pełnym adresem http:// albo https://, które otwierają się w nowej karcie (target="_blank"), mają rel="noopener" albo noreferrer. Brak to wskazówka z etykietą Bezpieczeństwo, bo obecne wersje Chrome, Firefox, Safari i Edge same dodają noopener, więc ryzyko dotyczy starszych przeglądarek.
Skan sprawdza stronę główną i do 3 podstron. Wynik dostajesz w około minutę.
Kiedy zlecić to komuś: Brakujące proste nagłówki dodasz z hostingiem w kwadrans. Przy CSP na stronie z analityką, czatem, płatnościami i reklamami warto zlecić wdrożenie z okresem testów, żeby ochrona nie wyłączyła formularza ani koszyka. Zobacz pełny audyt.
Pytania i odpowiedzi
Czy brak nagłówków bezpieczeństwa obniża pozycję w Google?
Google nie wymienia ich w dokumentacji o jakości strony. Tam pyta tylko, czy strona działa przez HTTPS, i ma na to osobny raport w Search Console. Nagłówki chronią klientów i Twoją markę przed skutkami ataków.
Czy mała strona wizytówka też ich potrzebuje?
Tak, bo automatyczne ataki wybierają strony po znanych lukach, a nie po wielkości firmy. Na wizytówce wdrożenie jest najprostsze.
Czy CSP może zepsuć stronę?
Może, jeśli zablokuje skrypt, z którego strona korzysta, na przykład czat albo mapę. Dlatego zaczyna się od trybu Content-Security-Policy-Report-Only, który tylko raportuje, i dopiero po testach włącza blokowanie.
Mam stronę na Cloudflare. Czy to wystarczy?
Cloudflare daje HTTPS i włącza HSTS przełącznikiem. CSP, ochronę przed ramką i resztę nagłówków ustawisz osobno, regułą nagłówków albo na serwerze.
Źródła
- RFC 6797: HTTP Strict Transport Security (HSTS)
- HSTS Preload List: wymagania i zalecenia
- web.dev: ścisła Content Security Policy
- MDN: X-Frame-Options
- MDN: X-Content-Type-Options
- MDN: Referrer-Policy
- MDN: mixed content
- MDN HTTP Observatory
- Cloudflare: HTTP Strict Transport Security (HSTS)
- Google Search Central: jakość strony (page experience)