nagłówki bezpieczeństwa HTTP
| Po angielsku | HTTP security headers |
|---|---|
| Którą formą pisać | po polsku Polska nazwa przyjęła się w tekstach i w wyszukiwarce — używaj jej samodzielnie. |
| Inne formy | nagłówki HTTP związane z bezpieczeństwem · nagłówki odpowiedzi zwiększające bezpieczeństwo |
| Kategoria | Strony WWW, WordPress i hosting |
Nagłówki bezpieczeństwa HTTP to nagłówki odpowiedzi serwera, którymi strona instruuje przeglądarkę, jakich ryzykownych zachowań ma unikać: ładowania skryptów z nieznanych źródeł, wyświetlania strony w cudzej ramce, zgadywania typu pliku albo łączenia się bez szyfrowania. OWASP zbiera zalecane wartości w osobnym zestawieniu i wymienia wśród nich między innymi Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options i Referrer-Policy [1]. Nagłówki nie usuwają błędów w kodzie strony. Ograniczają to, co atakujący może osiągnąć, gdy taki błąd istnieje.
Jak działa
Serwer dołącza nagłówki do każdej odpowiedzi, zwykle niezależnie od jej treści. Przeglądarka je odczytuje i stosuje ograniczenia do tej strony, a w przypadku HSTS zapamiętuje je na dłużej [2]. Cała ochrona działa więc po stronie klienta: nagłówek, którego przeglądarka nie zna, nie daje żadnego skutku, a nagłówek pominięty w części odpowiedzi zostawia tę część bez ochrony.
Schemat poniżej pokazuje przykład z ochroną przed osadzaniem w ramce. Strona wysyła nagłówek, a przeglądarka odmawia wyświetlenia jej wewnątrz obcej witryny.
Rodzaje
| Nagłówek | Cel | Zalecana wartość |
|---|---|---|
Strict-Transport-Security | tylko HTTPS dla domeny | długi max-age, includeSubDomains [1] |
Content-Security-Policy | ograniczenie źródeł skryptów i innych zasobów | polityka ograniczająca skrypty [3] |
X-Frame-Options | zakaz osadzania w ramce | DENY albo frame-ancestors w CSP [1] |
X-Content-Type-Options | zakaz zgadywania typu MIME | nosniff [1] |
Referrer-Policy | mniej danych w nagłówku Referer | strict-origin-when-cross-origin [1] |
Strict-Transport-Security. Nagłówek HSTS (HTTP Strict Transport Security) opisuje RFC 6797 z listopada 2012 roku jako mechanizm, którym witryna deklaruje, że jest dostępna tylko przez bezpieczne połączenia [2]. Dyrektywa max-age określa w sekundach, jak długo przeglądarka traktuje host jako znany host HSTS, a includeSubDomains rozciąga zasadę na subdomeny [2]. Przy błędzie TLS na takim hoście przeglądarka musi zerwać połączenie, bez możliwości zignorowania ostrzeżenia przez użytkownika [2]. CERT Polska podaje przykład z max-age=31536000, czyli rokiem [8]. Opisuje też skutek: przeglądarka pamięta wymaganie przez podany czas i nie wysyła niezaszyfrowanych żądań do domeny, nawet gdy użytkownik wpisze adres bez https:// albo kliknie link prowadzący do wersji HTTP [8]. Słabością mechanizmu jest pierwsza wizyta: zanim przeglądarka pozna zasadę, połączenie po HTTP może zostać przechwycone [2].
Content-Security-Policy. MDN opisuje CSP (Content Security Policy) jako zestaw instrukcji ograniczających to, co kod strony może robić, stosowany głównie przeciw XSS (Cross-Site Scripting) [3]. Nie zastępuje on czyszczenia danych wejściowych [3].
Osadzanie w ramce. X-Frame-Options i dyrektywa CSP frame-ancestors chronią przed clickjackingiem; OWASP zaleca frame-ancestors, a dla starszych przeglądarek X-Frame-Options: DENY [1].
Nagłówki do usunięcia. OWASP zaleca nie ustawiać X-XSS-Protection albo jawnie go wyłączyć wartością 0, bo ten starszy mechanizm sam może tworzyć podatności [1]. Zaleca też usunięcie albo zaciemnienie Server i X-Powered-By, bo zdradzają użyte technologie [1]; to przykład ujawniania wersji.
Typ treści i Referer. Wartość nosniff w X-Content-Type-Options wyłącza zgadywanie typu MIME, przez które plik nieprzeznaczony do wykonania mógłby zostać potraktowany jak kod [1]. Referrer-Policy określa, ile informacji o adresie strony źródłowej trafia do innych domen razem z żądaniem [1].
Dodatkowo OWASP wymienia Permissions-Policy do wyłączania zbędnych funkcji przeglądarki, na przykład geolokalizacji i kamery, oraz Cross-Origin-Opener-Policy: same-origin do izolacji kontekstu przeglądania [1].
W WordPressie
Rdzeń WordPressa wysyła tylko część nagłówków i tylko w wybranych miejscach. Funkcja send_frame_options_header(), obecna od wersji 3.1.3, wysyła X-Frame-Options: SAMEORIGIN oraz Content-Security-Policy: frame-ancestors 'self' [4]. Jest podpięta pod akcję admin_init, czyli działa w panelu [5], oraz pod login_init, czyli na stronie logowania [6]. REST API dodaje do swoich odpowiedzi X-Content-Type-Options: nosniff [7].
Strony publiczne motywu nie dostają od rdzenia ani HSTS, ani pełnej polityki CSP. Te nagłówki ustawia się w konfiguracji serwera, w reverse proxy lub CDN albo przez wtyczkę bezpieczeństwa. Na serwerze Apache robi się to często w pliku .htaccess; zob. zabezpieczenia w .htaccess. Przykład ilustracyjny, wymagający modułu mod_headers:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set X-Frame-Options "SAMEORIGIN"
Polityka CSP dla WordPressa wymaga osobnej pracy. Motywy i wtyczki mogą wstawiać skrypty w linii, a polityka z dyrektywą script-src blokuje je bez dodatkowego oznaczenia, na przykład nonce albo skrótu [3]. Dlatego CSP zwykle wprowadza się stopniowo, po przeglądzie zasobów strony.
Znaczenie
Brak nagłówków sam w sobie nie jest podatnością, którą da się wykorzystać bezpośrednio. Zwiększa jednak skutki innych błędów: przy braku CSP wstrzyknięty skrypt działa bez ograniczeń, przy braku HSTS atakujący w sieci może próbować ataku man-in-the-middle (MITM) na pierwsze połączenie po HTTP [2], a przy braku ochrony ramek panel można osadzić w obcej stronie. Z tego powodu brakujące albo błędne nagłówki opisuje się jako błędną konfigurację zabezpieczeń.
Nagłówki uzupełniają inne ustawienia przeglądarki, takie jak flagi ciasteczek. Razem tworzą warstwę ochrony, która działa niezależnie od kodu wtyczek.
Dobre praktyki
- Włączyć HSTS dopiero wtedy, gdy cała domena i subdomeny działają po HTTPS z ważnym certyfikatem. OWASP zaleca wcześniejsze sprawdzenie poprawności konfiguracji TLS [1], bo przy błędzie certyfikatu przeglądarka nie pozwoli wejść na stronę [2].
- Usunąć z odpowiedzi
X-Powered-Byz wersją PHP i szczegóły nagłówkaServer[1]. - Wysyłać
Content-Typez poprawnym typem i kodowaniem znaków, na przykładtext/html; charset=UTF-8[1]. - Wprowadzać CSP stopniowo i sprawdzać, czy polityka nie blokuje funkcji panelu.
- Po każdej zmianie sprawdzić nagłówki na kilku typach adresów: strona główna, wpis, panel, REST API, pliki statyczne. Nagłówki ustawione tylko dla części odpowiedzi łatwo przeoczyć.
Przypisy
8- [1] HTTP Security Response Headers Cheat Sheet · OWASP
- [2] RFC 6797: HTTP Strict Transport Security (HSTS) · IETF
- [3] Content Security Policy (CSP) · MDN Web Docs
- [4] send_frame_options_header() — Code Reference · WordPress.org
- [5] admin-filters.php (wordpress-develop) · WordPress.org / GitHub
- [6] default-filters.php (wordpress-develop) · WordPress.org / GitHub
- [7] class-wp-rest-server.php (wordpress-develop) · WordPress.org / GitHub
- [8] TLS — bezpieczeństwo webowe · CERT Polska