Nagłówki odpowiedzi HTTP mówią przeglądarce, jak traktować Państwa strony: które skrypty mogą być uruchamiane, czy stronę można osadzić w ramce i czy zawsze musi być ładowana przez HTTPS. Kilka z nich niemal bez kosztów blokuje całe klasy ataków. Inne są przestarzałe i jedynie dodają szumu, a nawet ryzyka.
Konfiguracja bazowa na początek
To rozsądny punkt wyjścia dla aplikacji HTML serwowanej wyłącznie przez HTTPS. Nie należy jej wklejać bez zmian. Zwłaszcza CSP musi odpowiadać temu, jak Państwa strony ładują skrypty, wartość nonce musi być nowa przy każdej odpowiedzi, a wpis HSTS preload trudno cofnąć.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: script-src 'nonce-3f9a1c7e2b' 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-site
Content-Security-Policy
CSP ogranicza, skąd mogą pochodzić skrypty i inne zasoby. Jej głównym zadaniem jest znaczne utrudnienie wykorzystania podatności cross-site scripting (XSS).
Ściągawka OWASP dotycząca CSP przedkłada restrykcyjną politykę opartą na wartościach nonce lub skrótach nad długą listę dozwolonych domen. Polityki oparte na listach dozwolonych, które są zbyt szerokie lub zbyt szczegółowe, często daje się obejść. Polityka oparta na nonce wygląda tak:
Content-Security-Policy: script-src 'nonce-3f9a1c7e2b' 'strict-dynamic'; object-src 'none'; base-uri 'none'
Każdy znacznik script ma wtedy tę samą wartość, jak w <script nonce="3f9a1c7e2b">. Nonce musi być losowy i nowy przy każdej odpowiedzi; stała wartość niweczy cały sens. Należy go generować w warstwie szablonów. OWASP ostrzega przed oprogramowaniem pośredniczącym (middleware), które dodaje nonce do każdego znacznika script, ponieważ „uwierzytelniłoby” ono także wstrzyknięte skrypty.
Jeśli strony są statyczne, lepiej użyć skrótów: wartości 'sha256-...' dla każdego skryptu inline. Każda zmiana skryptu, nawet w białych znakach, zmienia skrót.
W script-src należy unikać 'unsafe-inline' i 'unsafe-eval'. Otwierają one dokładnie to, co CSP ma zamykać.
Aby wdrożyć politykę bez psucia strony, najpierw należy wysyłać ją jako Content-Security-Policy-Report-Only. Przeglądarki zgłaszają wtedy naruszenia, niczego nie blokując. Po usunięciu problemów wskazanych w raportach można przejść na egzekwowanie.
Trusted Types
Trusted Types są wymierzone w XSS oparty na DOM, w którym własny kod JavaScript przekazuje ciągi kontrolowane przez atakującego do niebezpiecznych interfejsów API, takich jak innerHTML, eval() czy src elementu script. Włącza się je za pomocą CSP:
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-policy
Przy włączonym egzekwowaniu przekazanie zwykłego ciągu znaków do jednego z tych miejsc docelowych zgłasza błąd. Kod musi przekazywać wartości utworzone przez nazwaną politykę, zwykle taką, która oczyszcza HTML. MDN oznacza to API jako Baseline od lutego 2026 roku, co oznacza, że działa w aktualnych wersjach głównych przeglądarek. Warto zacząć od trybu report-only, ponieważ istniejący kod może zapisywać ciągi znaków bezpośrednio w DOM.
Strict-Transport-Security i preload
HSTS każe przeglądarkom łączyć się z Państwa domeną wyłącznie przez HTTPS przez liczbę sekund podaną w max-age. Z includeSubDomains reguła obejmuje także wszystkie subdomeny.
Lista preload idzie dalej. Przeglądarki mają ją wbudowaną, więc nawet pierwsza wizyta w Państwa domenie odbywa się przez HTTPS. Wymagania podane na hstspreload.org to:
- prawidłowy certyfikat i przekierowanie z HTTP na HTTPS na tym samym hoście
- wszystkie subdomeny serwowane przez HTTPS, łącznie z wewnętrznymi
max-agewynoszący co najmniej 31536000 (jeden rok) orazincludeSubDomainsipreload- nagłówek HSTS również w przekierowaniach wysyłanych przez stronę HTTPS
Wdrażać należy etapami. Strona listy preload sugeruje zacząć od max-age=300, potem tydzień (604800), potem miesiąc (2592000), obserwując na każdym etapie, czy coś przestało działać. Usunięcie z listy preload dociera do użytkowników po miesiącach, dlatego trzeba mieć pewność, że każda subdomena może długoterminowo obsługiwać HTTPS.
X-Content-Type-Options
X-Content-Type-Options: nosniff powstrzymuje przeglądarki przed odgadywaniem typu pliku na podstawie jego zawartości. Należy łączyć go z prawidłowym nagłówkiem Content-Type w każdej odpowiedzi, łącznie z charset dla HTML, np. text/html; charset=UTF-8.
frame-ancestors i X-Frame-Options
Clickjacking polega na niewidocznym załadowaniu Państwa strony w ramce na innej stronie. Dyrektywa CSP frame-ancestors określa, kto może osadzać Państwa stronę, a OWASP zauważa, że w obsługujących ją przeglądarkach zastępuje ona X-Frame-Options.
Dwa szczegóły często zaskakują. Według MDN frame-ancestors nie dziedziczy wartości z default-src, więc trzeba ją ustawić jawnie. Nie działa też w znaczniku <meta>; działa wyłącznie jako nagłówek. Ze względu na starsze przeglądarki wysyłanie obu nie szkodzi:
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
Jeśli Państwa własna strona osadza swoje podstrony w ramkach, należy użyć frame-ancestors 'self'. Trzeba unikać przestarzałego X-Frame-Options: ALLOW-FROM. MDN zauważa, że nowoczesne przeglądarki po jego napotkaniu ignorują cały nagłówek.
Referrer-Policy
Ten nagłówek określa, jaka część bieżącego adresu URL jest wysyłana do innych stron w nagłówku Referer. Jeśli nic nie zostanie ustawione, przeglądarki domyślnie stosują strict-origin-when-cross-origin, które przez HTTPS wysyła do innych stron tylko źródło (origin). OWASP mimo to zaleca jawne ustawienie tego nagłówka. Jeśli adresy URL mogą zawierać tokeny lub dane osobowe, należy użyć no-referrer lub same-origin.
Permissions-Policy
Permissions-Policy wyłącza funkcje przeglądarki, z których strona nie korzysta. Pusta lista dozwolonych, (), wyłącza funkcję dla strony i każdej osadzonej w niej ramki:
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=()
Jeśli funkcja jest potrzebna, należy zezwolić na nią wąsko, np. camera=(self).
COOP i CORP
Cross-Origin-Opener-Policy: same-origin umieszcza stronę we własnej grupie kontekstów przeglądania. Strona, która otworzy Państwa stronę przez window.open(), nie może wtedy zachować do niej odwołania, co zamyka drogę dla jednej klasy ataków polegających na wyciekach między stronami (XS-Leaks). Jeśli korzystają Państwo z wyskakujących okien przy jednokrotnym logowaniu lub płatnościach, same-origin-allow-popups pozwala zachować ich działanie.
Cross-Origin-Resource-Policy: same-site uniemożliwia innym stronom osadzanie Państwa zasobów, takich jak obrazy czy skrypty. Cross-Origin-Embedder-Policy: require-corp jest potrzebny tylko do izolacji międzyźródłowej (cross-origin isolation), której wymagają funkcje takie jak SharedArrayBuffer. Jeśli te funkcje nie są potrzebne, COEP lepiej pominąć, ponieważ blokuje zasoby z innych źródeł, które nie wyraziły na to zgody.
Nagłówki do wycofania
| Nagłówek | Status | Co zrobić |
|---|---|---|
X-XSS-Protection | Wycofany i niestandardowy; MDN ostrzega, że może tworzyć podatności XSS w stronach, które poza tym są bezpieczne | Usunąć go lub wysyłać 0 i polegać na CSP |
Expect-CT | Wycofany | Usunąć go |
Public-Key-Pins | Usunięty z Chromium w 2018 roku | Usunąć go; zamiast tego korzystać z Certificate Transparency i rekordów CAA |
X-Frame-Options: ALLOW-FROM | Przestarzały | Używać frame-ancestors |
Server, X-Powered-By | Ujawniają oprogramowanie i wersje | Usunąć je lub ustawić neutralną wartość |
Od czego zacząć
- Sprawdzić, co dziś wysyła Państwa strona, za pomocą naszego skanera nagłówków bezpieczeństwa.
- Najpierw dodać nagłówki o niskim ryzyku:
X-Content-Type-Options,Referrer-Policy,Permissions-Policyiframe-ancestors. - Wdrożyć HSTS z krótkim
max-agei zwiększać go etapami. Preload rozważyć dopiero wtedy, gdy wszystkie subdomeny będą gotowe. - Przez kilka tygodni stosować CSP w trybie report-only, usunąć naruszenia, a następnie włączyć egzekwowanie.
Jeśli budują Państwo nową aplikację i chcą od początku uwzględnić te zabezpieczenia w projekcie, pomoże nasz zespół bezpiecznego oprogramowania.
