Nagłówki bezpieczeństwa HTTP
Nagłówki bezpieczeństwa to dyrektywy wysyłane przez serwer w odpowiedzi HTTP, które instruują przeglądarkę jak ma się zachowywać w określonych sytuacjach: skąd może ładować zasoby, czy zezwalać na osadzanie strony w ramkach, jak długo wymuszać HTTPS. Działają po stronie klienta — serwer deklaruje zasady, przeglądarka je egzekwuje.
Poprawnie skonfigurowane nagłówki ograniczają skutki ataków XSS, clickjackingu, przechwytywania sesji i wycieków informacji o infrastrukturze. Nie zastępują bezpiecznego kodu, ale stanowią dodatkową warstwę ochrony niezależną od aplikacji.
Omawiane nagłówki
| Nagłówek | Cel |
|---|---|
Content-Security-Policy | Kontrola źródeł zasobów, ochrona przed XSS |
Strict-Transport-Security | Wymuszenie HTTPS |
X-Content-Type-Options | Blokada MIME-sniffingu |
X-Frame-Options | Ochrona przed clickjackingiem |
Permissions-Policy | Kontrola dostępu do funkcji przeglądarki |
Referrer-Policy | Kontrola danych przesyłanych w nagłówku Referer |
Access-Control-Allow-Origin | Zasady współdzielenia zasobów między domenami (CORS) |
Content-Security-Policy
Content-Security-Policy (CSP) to jeden z najważniejszych nagłówków bezpieczeństwa. Pozwala określić, skąd przeglądarka może ładować skrypty, style, obrazy, fonty i inne zasoby. Jeżeli zasób pochodzi ze źródła, którego nie ma na liście, przeglądarka go blokuje — nawet jeśli atakujący zdołał wstrzyknąć złośliwy kod do strony.
Podstawowe dyrektywy
default-src— domyślne źródła dla wszystkich typów zasobów, których nie obejmują bardziej szczegółowe dyrektywyscript-src— źródła skryptów JavaScriptstyle-src— źródła arkuszy CSSimg-src— źródła obrazówfont-src— źródła fontówconnect-src— dozwolone połączenia (fetch, XHR, WebSocket)frame-src— źródła dla elementów<iframe>frame-ancestors— określa, które domeny mogą osadzać twoją stronę w ramce (zastępujeX-Frame-Options)object-src— źródła dla<object>,<embed>,<applet>
Słowa kluczowe
'self'— tylko bieżąca domena'none'— blokuje wszystkie źródła'unsafe-inline'— zezwala na kod inline (skrypty i style wbudowane w HTML) — używaj tylko gdy niezbędne'unsafe-eval'— zezwala naeval()i podobne funkcje — unikaj jeśli możliwe
Przykłady
Zezwolenie na zasoby tylko z własnej domeny i zaufanych CDN:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com;Blokada osadzania strony w ramkach przez inne domeny:
Content-Security-Policy: frame-ancestors 'self';Raportowanie naruszeń bez blokowania (tryb testowy):
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-raport;💡 Zacznij od trybu Report-Only
CSP jest trudny do skonfigurowania na działającej stronie — zbyt restrykcyjne ustawienia mogą zepsuć funkcjonalność. Użyj nagłówka Content-Security-Policy-Report-Only i przez kilka dni obserwuj raporty naruszeń zanim włączysz blokowanie.
Strict-Transport-Security
Strict-Transport-Security (HSTS) instruuje przeglądarkę, żeby przez określony czas łączyła się z twoją stroną wyłącznie przez HTTPS — nawet jeśli użytkownik wpisze adres z http://. Eliminuje możliwość przypadkowego niezaszyfrowanego połączenia i utrudnia ataki man-in-the-middle.
Parametry
max-age=<sekundy>— przez ile sekund przeglądarka ma pamiętać o wymuszeniu HTTPS.31536000to jeden rok.includeSubDomains— rozszerza politykę na wszystkie subdomeny twojej domenypreload— zgłasza domenę do wbudowanej listy HSTS przeglądarek (wymaga spełnienia wymagań i osobnej rejestracji na hstspreload.org)
Przykład
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload⚠️ Przed włączeniem HSTS
Upewnij się, że twoja strona w pełni działa przez HTTPS — wszystkie zasoby, subdomeny, przekierowania. HSTS z includeSubDomains obejmie każdą subdomenę, w tym te, które mogą nie mieć certyfikatu SSL. Błędna konfiguracja może zablokować dostęp do strony na czas określony w max-age.
X-Content-Type-Options
Zapobiega tzw. MIME-sniffingowi — sytuacji, w której przeglądarka próbuje samodzielnie zgadnąć typ zawartości pliku na podstawie jego treści, ignorując nagłówek Content-Type. Atakujący mogą wykorzystać to zachowanie, serwując złośliwy skrypt udający obraz.
Jedyna sensowna wartość to nosniff:
X-Content-Type-Options: nosniffPo ustawieniu tego nagłówka przeglądarka zawsze respektuje Content-Type zadeklarowany przez serwer, bez zgadywania.
X-Frame-Options
Kontroluje, czy twoja strona może być osadzana w elementach <iframe>, <frame> lub <object> na innych domenach. Chroni przed clickjackingiem — techniką, gdzie atakujący nakłada niewidoczną warstwę twojej strony na inną, skłaniając użytkownika do kliknięcia nieświadomie.
Wartości
DENY— całkowity zakaz osadzania strony w ramkachSAMEORIGIN— osadzanie dozwolone tylko przez tę samą domenę
X-Frame-Options: SAMEORIGININFO
X-Frame-Options jest nadal powszechnie obsługiwany, jednak nowocześniejszym odpowiednikiem jest dyrektywa frame-ancestors w nagłówku Content-Security-Policy. Daje więcej możliwości (np. zezwolenie konkretnej domenie zewnętrznej) i jest preferowana przez aktualne standardy. Oba nagłówki możesz ustawiać jednocześnie dla kompatybilności ze starszymi przeglądarkami.
Permissions-Policy
Permissions-Policy pozwala kontrolować dostęp do funkcji przeglądarki — geolokalizacji, kamery, mikrofonu, autoodtwarzania i innych — zarówno dla twojej strony, jak i dla osadzonych ramek iframe.
Składnia
Permissions-Policy: geolocation=(), camera=(), microphone=(), autoplay=(self)()— całkowity zakaz, nawet dla twojej strony(self)— dostęp tylko dla twojej domeny(self "https://partner.example.com")— dostęp dla twojej domeny i wskazanego partnera
Przykład dla typowej strony
Permissions-Policy: accelerometer=(), autoplay=(self), camera=(), geolocation=(), gyroscope=(), microphone=(), payment=(), picture-in-picture=(self), usb=()INFO
Feature-Policy to poprzednia nazwa tego nagłówka, używana przed 2020 rokiem. Przeglądarki w dużej mierze go zignorują lub obsłużą z ostrzeżeniami. Jeżeli gdzieś widzisz Feature-Policy — zastąp go Permissions-Policy.
Referrer-Policy
Kontroluje, jakie informacje o poprzedniej stronie (nagłówek Referer) przeglądarka przekazuje przy nawigacji i żądaniach do zasobów zewnętrznych. Bez tego nagłówka przeglądarka może wysyłać pełny URL — łącznie z parametrami zapytania, tokenami w URL czy ścieżkami do wewnętrznych podstron.
Główne wartości
| Wartość | Zachowanie |
|---|---|
no-referrer | Referer nigdy nie jest wysyłany |
strict-origin | Wysyła tylko domenę, tylko przy HTTPS→HTTPS |
strict-origin-when-cross-origin | Pełny URL dla tej samej domeny, tylko domena dla cross-origin |
no-referrer-when-downgrade | Pełny URL przy HTTPS→HTTPS, nic przy HTTPS→HTTP |
unsafe-url | Zawsze pełny URL — unikaj |
Dobry kompromis między bezpieczeństwem a użytecznością analityczną:
Referrer-Policy: strict-origin-when-cross-origin💡 Dlaczego to ważne?
Jeżeli twoja strona ma w URL tokeny resetowania haseł, identyfikatory sesji lub wewnętrzne ścieżki — bez Referrer-Policy te wartości mogą wyciec do zewnętrznych serwisów (np. przez załadowanie zewnętrznego skryptu analitycznego).
Access-Control-Allow-Origin
Nagłówek związany z mechanizmem CORS (Cross-Origin Resource Sharing). Określa, które domeny mogą pobierać zasoby z twojego serwera przez żądania cross-origin (np. JavaScript z innej domeny wywołujący twoje API).
Wartości
*— każda domena może pobierać zasoby (stosuj tylko dla publicznych API bez uwierzytelnienia)https://zaufana-domena.pl— dostęp tylko dla wskazanej domeny
Access-Control-Allow-Origin: https://aplikacja.twojadomena.pl⚠️ Wildcard i ciasteczka
Access-Control-Allow-Origin: * nie działa razem z Access-Control-Allow-Credentials: true. Jeżeli twoje API używa ciasteczek do uwierzytelnienia, musisz podać konkretną domenę zamiast *.
INFO
Access-Control-Allow-Origin jest nagłówkiem odpowiedzi dla zasobów udostępnianych innym serwisom, a nie mechanizmem ochrony twojej strony przed zewnętrznymi żądaniami. Nie zastępuje uwierzytelnienia ani walidacji po stronie serwera.
Jak sprawdzić aktualne nagłówki
Najszybciej przez securityheaders.com — wpisz adres swojej strony i otrzymasz ocenę A–F z listą brakujących i niepoprawnych nagłówków.
Alternatywnie przez terminal:
curl -I https://twojadomena.plAby wyfiltrować tylko nagłówki bezpieczeństwa:
curl -sI https://twojadomena.pl | grep -iE "content-security|strict-transport|x-content|x-frame|permissions|referrer"Wdrożenie przez .htaccess
Na hostingu Joton (LiteSpeed) i klasycznym Apache nagłówki ustawia się w pliku .htaccess w katalogu głównym strony. Plik możesz edytować przez Menedżer plików w panelu Joton lub przez FTP/SSH.
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Permitted-Cross-Domain-Policies "none"
Header always unset X-Powered-By
Header always unset Server
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "accelerometer=(), autoplay=(self), camera=(), encrypted-media=(self), fullscreen=(self), geolocation=(self), microphone=(), midi=(), payment=(), picture-in-picture=(self)"
Header always set Content-Security-Policy "default-src 'self'; object-src 'none'; script-src 'self' https: data: blob: 'unsafe-inline' 'unsafe-eval'; connect-src 'self' https:; style-src 'self' https: 'unsafe-inline'; font-src 'self' data: https:; img-src 'self' blob: data: https:; frame-src 'self' https: blob:; frame-ancestors 'self';"
</IfModule><IfModule mod_headers.c>
Header set X-Frame-Options "SAMEORIGIN"
Header set X-Content-Type-Options "nosniff"
Header set X-Permitted-Cross-Domain-Policies "none"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "accelerometer=(), autoplay=(self), camera=(), geolocation=(self), microphone=(), payment=()"
Header set Content-Security-Policy "upgrade-insecure-requests; default-src 'self'; script-src 'self' https: 'unsafe-inline'; style-src 'self' https: 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https: data:;"
Header always unset X-Powered-By
Header unset X-Powered-By
</IfModule>💡 Header set vs Header always set
Header always set ustawia nagłówek we wszystkich odpowiedziach serwera — łącznie z błędami (404, 500). Header set działa tylko przy odpowiedziach 2xx. Na LiteSpeed użyj always aby nagłówki były obecne nawet na stronach błędów.
Uwagi i niepożądane skutki
Nagłówki bezpieczeństwa mogą powodować problemy jeśli są zbyt restrykcyjne:
- CSP i zewnętrzne skrypty — zbyt wąskie
script-srczablokuje skrypty analityczne, chat widgety, mapy Google. Przed wdrożeniem sprawdź przezContent-Security-Policy-Report-Only. - HSTS i brakujące certyfikaty — jeśli subdomena nie ma SSL a włączyłeś
includeSubDomains, przeglądarka zablokuje do niej dostęp na cały czasmax-age. - Permissions-Policy i wtyczki WordPress — niektóre wtyczki (np. płatności, reCAPTCHA) wymagają dostępu do funkcji przeglądarki. Zbyt restrykcyjna polityka może je zablokować.
Zawsze testuj nagłówki najpierw na środowisku stagingowym zanim wdrożysz na produkcję.
X-XSS-Protection (przestarzały)
Nagłówek X-XSS-Protection był obsługiwany przez starsze przeglądarki (Internet Explorer, stary Edge, Chrome przed wersją 78) i uruchamiał wbudowany filtr XSS. Współczesne przeglądarki (Chrome 78+, Firefox, nowy Edge) całkowicie go ignorują lub usunęły wsparcie.
Nie wdrażaj go na nowych stronach — w niektórych konfiguracjach mógł paradoksalnie wprowadzać nowe podatności. Zamiast niego używaj Content-Security-Policy.
Jeżeli widzisz go w istniejącej konfiguracji .htaccess, możesz go bezpiecznie usunąć.
Przydatne linki
- Skrzynki e-mail — konfiguracja poczty na hostingu Joton
- Bezpieczeństwo ciasteczek — flagi Secure, HttpOnly, SameSite
- Bezpieczeństwo WordPress — hardening instalacji WordPress
- securityheaders.com — sprawdzanie i ocenianie nagłówków bezpieczeństwa
- MDN: HTTP Headers — pełna dokumentacja nagłówków HTTP