Przejdź do treści
🔒 HTTP security headers dla WordPress: pełny przewodnik konfiguracji

🔒 HTTP security headers dla WordPress: pełny przewodnik konfiguracji

Strona na WordPress działa, wtyczka bezpieczeństwa jest zainstalowana, ale test na securityheaders.com pokazuje ocenę F. Brzmi znajomo?

Nagłówki bezpieczeństwa HTTP to niewidoczna warstwa ochrony, o której zapomina się nawet po skonfigurowaniu firewalla i uwierzytelniania dwuskładnikowego. Nie wymagają odnawiania licencji, nie obciążają serwera i blokują całe klasy ataków: od clickjackingu po przechwytywanie sesji. A dodaje się je w 10 minut.

Poniżej, krok po kroku: które nagłówki są naprawdę potrzebne, jak je skonfigurować przez.htaccess, functions.php lub wtyczkę i jak sprawdzić, czy ochrona działa, a nie tylko widnieje.

💡 Szybki przegląd:

  • Sprawdź obecne nagłówki strony przez securityheaders.com lub Mozilla Observatory, zobaczysz rzeczywisty obraz
  • Włącz podstawowy zestaw 4-5 nagłówków: X-Content-Type-Options, X-Frame-Options, HSTS, Referrer-Policy, Permissions-Policy
  • Wybierz sposób: kilka linii w.htaccess (Apache/LiteSpeed), snippet w functions.php lub wtyczka Headers Security Advanced & HSTS WP
  • CSP zostaw na później, jest skomplikowany w konfiguracji i psuje Gutenberga, jeśli zrobi się to bez testowania
  • Po wdrożeniu wykonaj ponowny test, ocena A+ jest osiągalna w 10 minut

Czym są nagłówki bezpieczeństwa HTTP

Gdy przeglądarka żąda strony, serwer WWW odsyła nie tylko kod HTML. Każda odpowiedź HTTP zawiera pola serwisowe, czyli nagłówki. Część z nich odpowiada za buforowanie i typ treści, a część za bezpieczeństwo.

Przeglądarka odczytuje nagłówki bezpieczeństwa jeszcze zanim zacznie renderować stronę. Jeśli serwer mówi „zabraniam osadzania tej strony w ramkach", przeglądarka tego nie zrobi, nawet jeśli w kodzie strony jest <iframe>. Jeśli serwer mówi „przez rok działamy tylko po HTTPS", przeglądarka to zapamięta i nie przejdzie na wersję HTTP, nawet jeśli użytkownik ręcznie ją wpisze.

Żaden JavaScript, żadna wtyczka, żaden firewall nie mają na to wpływu. To jest poziom protokołu. Właśnie dlatego nagłówki stanowią odrębną, samodzielną linię obrony.

Dlaczego jest to potrzebne stronie na WordPress

Wtyczki bezpieczeństwa takie jak Wordfence czy Solid Security zamykają luki na poziomie aplikacji: brute force, iniekcje, szkodliwe pliki. Nagłówki HTTP działają poziom wyżej, chronią sam kanał komunikacji między serwerem a odwiedzającym.

Oto, co blokują poprawnie skonfigurowane nagłówki:

  • Clickjacking. Atakujący osadza Pana/Pani stronę w przezroczystej ramce na swojej stronie i przechwytuje kliknięcia użytkownika. Blokowane przez nagłówek X-Frame-Options lub dyrektywę frame-ancestors w CSP.

  • MIME sniffing. Przeglądarka próbuje „zgadnąć" typ pliku i może wykonać przesłany obraz jako JavaScript. Blokowane przez X-Content-Type-Options: nosniff.

  • Przechwytywanie sesji. Atakujący w otwartej sieci Wi-Fi podmienia odpowiedź serwera i kradnie ciasteczko logowania. HSTS zabrania przeglądarce łączenia się z wersją HTTP strony.

  • Wyciek referera. Przy przejściu przez zewnętrzny link strona docelowa widzi, z której strony przyszedł użytkownik, włącznie z URL-em z parametrami. Referrer-Policy to ogranicza.

  • Nieautoryzowany dostęp do urządzeń. Strona internetowa żąda mikrofonu, kamery lub geolokalizacji bez wiedzy użytkownika. Permissions-Policy zabrania takich żądań na poziomie przeglądarki.

CSP dodaje kolejną warstwę: dokładnie określa Pan/Pani, z jakich domen można ładować skrypty, style i czcionki. Nawet jeśli szkodliwy kod trafi do bazy danych, przeglądarka go nie wykona, bo źródła nie ma na białej liście. Ale CSP wymaga ostrożności: mała pomyłka i edytor Gutenberg przestanie działać.

Kluczowe nagłówki bezpieczeństwa HTTP: co zawierają i dlaczego

Poniżej nagłówki, które warto skonfigurować na każdej stronie WordPress. Dla każdego podano: przed jakim atakiem chroni, zalecaną wartość i gdzie może się zepsuć.

X-Content-Type-Options

Najprostszy i najbezpieczniejszy w konfiguracji. Jedyna dopuszczalna wartość to nosniff. Przeglądarka przestaje „zgadywać" typ MIME pliku po zawartości i ufa tylko typowi, który przekazał serwer w nagłówku Content-Type.

Bez tego nagłówka przeglądarka może uznać przesłany przez użytkownika obraz za skrypt i go wykonać, to klasyczny scenariusz ataku przez upload plików.

Zalecana wartość: nosniff

Ryzyko awarii: minimalne. Problemy są możliwe tylko wtedy, gdy serwer odsyła pliki z nieprawidłowym Content-Type, ale to osobny problem, który warto naprawić, a nie maskować.

X-Frame-Options

Kontroluje, czy Pana/Pani strona może być osadzona w <frame>, <iframe> lub <object> na obcej stronie.

Dwie główne wartości:

  • DENY, całkowity zakaz osadzania. Maksymalna ochrona.
  • SAMEORIGIN, dozwolone osadzanie tylko z tej samej domeny. Potrzebne, jeśli sam używa Pan/Pani ramek do własnych stron (np. podgląd w panelu administracyjnym).

Dla większości stron WordPress odpowiednie jest SAMEORIGIN. Jeśli ma Pan/Pani pewność, że żadne ramki nie są używane, proszę ustawić DENY.

Zalecana wartość: SAMEORIGIN

Ryzyko awarii: niektóre wtyczki używają iframe do podglądu. Jeśli po włączeniu DENY coś przestało się wyświetlać w panelu administracyjnym, proszę przełączyć na SAMEORIGIN.

Strict-Transport-Security (HSTS)

Mówi przeglądarce: „przez najbliższe N sekund łącz się z tą domeną tylko przez HTTPS". Chroni przed atakami downgrade i przechwytywaniem ciasteczek w otwartych sieciach.

Kluczowy parametr to max-age. Zaleca się zaczynać od małej wartości (doba lub tydzień) i po sprawdzeniu zwiększać do roku.

Opcjonalny parametr includeSubDomains rozszerza regułę na wszystkie subdomeny, co jest ważne, jeśli ma ich Pan/Pani kilka i używa CDN.

Parametr preload dodaje stronę do globalnej listy HSTS przeglądarek: Chrome, Firefox i Safari będą łączyć się z Pana/Pani domeną tylko przez HTTPS jeszcze przed pierwszym żądaniem. Zgłoszenie przez hstspreload.org.

Zalecana wartość: max-age=31536000; includeSubDomains

Ryzyko awarii: jeśli włączy Pan/Pani HSTS, a certyfikat SSL wygaśnie, użytkownicy w ogóle nie wejdą na stronę. Proszę pilnować automatycznego odnawiania certyfikatu.

Referrer-Policy

Zarządza tym, jakie informacje o stronie źródłowej przeglądarka przekazuje przy przejściu przez link na inną stronę.

Główne wartości, od najostrzejszej do najłagodniejszej:

  • no-referrer, w ogóle nic nie jest przekazywane.
  • strict-origin-when-cross-origin, na inną domenę przekazywana jest tylko domena (bez ścieżki i parametrów); na własną, pełny URL. Optymalna równowaga prywatności i analityki.
  • strict-origin, zawsze tylko domena, bez ścieżki.

Jeśli w ogóle nie chce Pan/Pani, aby strony docelowe wiedziały, skąd przyszedł użytkownik, proszę ustawić no-referrer. Proszę jednak pamiętać: straci Pan/Pani ruch z poleceń we własnej analityce.

Zalecana wartość: strict-origin-when-cross-origin

Ryzyko awarii: minimalne. Niektóre zewnętrzne serwisy mogą wymagać referera do działania (np. bramki płatności z weryfikacją źródła). Takie przypadki można śledzić przez konsolę przeglądarki.

Permissions-Policy

Wcześniej nazywała się Feature-Policy. Ogranicza dostęp strony internetowej do „sprzętowych" API przeglądarki: mikrofonu, kamery, geolokalizacji, USB, API płatności i tak dalej.

Format: название-фичи=(разрешённый-источник). Na przykład:

1Permissions-Policy: camera=(), microphone=(), geolocation=(self)

Ten przykład całkowicie zabrania dostępu do kamery i mikrofonu dla wszystkich źródeł, a geolokalizację zezwala tylko dla samej strony (self).

Pełna lista funkcji na MDN. Dla strony WordPress bez wideorozmów i funkcji PWA wystarczy zablokować kamerę, mikrofon i geolokalizację, reszta jest opcjonalna.

Zalecana wartość: zależy od funkcjonalności strony. Minimum to camera=(), microphone=(), geolocation=(self).

Ryzyko awarii: jeśli na stronie jest funkcja wideorozmów, PWA lub WebUSB, proszę sprawdzić, jakich funkcji potrzebuje i ich nie blokować.

Content-Security-Policy (CSP)

Najpotężniejszy i najbardziej ryzykowny w konfiguracji nagłówek. Określa białą listę źródeł dla skryptów, stylów, czcionek, obrazów, ramek i innych zasobów.

Przykład minimalnej polityki dla WordPress:

1Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;
2

*Dlaczego unsafe-inline i unsafe-eval:* WordPress, Gutenberg i dziesiątki wtyczek generują skrypty inline i używają eval(). Bez tych dyrektyw panel administracyjny po prostu przestanie działać. To cena za kompatybilność.

Zalecenie: proszę nie włączać CSP w pierwszej kolejności. Najpierw proszę skonfigurować pozostałe 5 nagłówków. CSP proszę wdrażać tylko wtedy, gdy ma Pan/Pani zasoby na testowanie i monitorowanie, proszę zacząć od trybu Content-Security-Policy-Report-Only i zbierać logi naruszeń przez kilka tygodni, zanim przejdzie Pan/Pani w tryb enforce.

Ryzyko awarii: wysokie. Błąd w CSP może całkowicie zepsuć frontend i panel administracyjny. Zawsze proszę testować na środowisku stagingowym lub przez Report-Only.

Jak sprawdzić obecne nagłówki strony

Przed konfiguracją, audyt. Trzy narzędzia, od prostego do szczegółowego:

  • securityheaders.com, wpisuje Pan/Pani URL i otrzymuje ocenę od A+ do F z wyjaśnieniem dla każdego nagłówka. Bezpłatnie, bez rejestracji.

  • Mozilla Observatory, bardziej szczegółowy audyt: ocenia nie tylko nagłówki, ale i konfigurację TLS, atrybuty ciasteczek, CORS i inne aspekty. Również bezpłatnie.

  • Chrome DevTools, proszę otworzyć zakładkę Network, wybrać dowolne żądanie do Pana/Pani strony i spojrzeć na sekcję Response Headers. Szybki sposób, by sprawdzić, czy zmiany „weszły" po edycji.htaccess.

Proszę sprawdzić stronę teraz. Jeśli ocena jest poniżej B, nie ma Pan/Pani nawet podstawowych nagłówków, a jedną trzecią punktów poniżej ustawi Pan/Pani w 5 minut.

Sposoby konfiguracji nagłówków HTTP w WordPress

Trzy ścieżki, od ręcznej do automatycznej. Proszę wybrać odpowiednią do swojej sytuacji.

Sposób 1: Przez.htaccess (Apache/LiteSpeed)

Najszybszy sposób dla stron na Apache lub LiteSpeed. Proszę dodać w .htaccess w katalogu głównym strony (przed # BEGIN WordPress):

1<IfModule mod_headers.c>
2 Header set X-Content-Type-Options "nosniff"
3 Header set X-Frame-Options "SAMEORIGIN"
4 Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
5 Header set Referrer-Policy "strict-origin-when-cross-origin"
6 Header set Permissions-Policy "camera=(), microphone=(), geolocation=(self)"
7</IfModule>

Warunek <IfModule mod_headers.c> gwarantuje, że strona nie padnie z błędem 500, jeśli moduł mod_headers nie jest włączony. Jeśli ma Pan/Pani pewność, że jest aktywny, można bez niego.

Po zapisaniu proszę wykonać w terminalu (jeśli jest WP-CLI) lub po prostu otworzyć stronę i sprawdzić nagłówki przez securityheaders.com. Zmiany w .htaccess są stosowane natychmiast, restart serwera nie jest potrzebny.

Sposób 2: Przez functions.php (Nginx / uniwersalny)

Działa niezależnie od serwera WWW, pasuje zarówno do Nginx, jak i Apache. Proszę dodać w functions.php motywu potomnego lub przez wtyczkę Code Snippets:

1function sdstudio_add_security_headers() {
2 header( 'X-Content-Type-Options: nosniff' );
3 header( 'X-Frame-Options: SAMEORIGIN' );
4 header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains' );
5 header( 'Referrer-Policy: strict-origin-when-cross-origin' );
6 header( 'Permissions-Policy: camera=(), microphone=(), geolocation=(self)' );
7}
8add_action( 'send_headers', 'sdstudio_add_security_headers' );

Hook send_headers uruchamia się wcześniej, niż WordPress zacznie odsyłać treść, nagłówki idą w pierwszej odpowiedzi serwera.

Dla Nginx ten sposób jest lepszy niż ingerowanie w konfigurację serwera (szczególnie na hostingu współdzielonym, gdzie często nie ma dostępu do nginx.conf). Minus: nagłówki działają tylko dla żądań PHP, które przechodzą przez WordPress. Pliki statyczne (obrazy, CSS, JS) są obsługiwane bezpośrednio przez Nginx i nie otrzymają nagłówków. Dla nich potrzebna będzie konfiguracja na poziomie serwera.

Sposób 3: Przez wtyczkę Headers Security Advanced & HSTS WP

Jeśli nie chce Pan/Pani dotykać kodu, proszę użyć specjalnej wtyczki. Headers Security Advanced & HSTS WP zbiera wszystkie nagłówki bezpieczeństwa w jednym interfejsie i włącza je jednym przyciskiem.

Wtyczka ustawia wstępnie zdefiniowane wartości dla wszystkich kluczowych nagłówków od razu po aktywacji: X-Content-Type-Options, X-Frame-Options, HSTS, CSP, Referrer-Policy, Permissions-Policy i szereg dodatkowych (CORP, COOP, COEP). Każdy nagłówek można wyłączyć lub przekonfigurować pod siebie.

Plus tego podejścia: wtyczka nie zależy od serwera WWW i działa tak samo na Apache, Nginx, LiteSpeed i IIS. Przy dezaktywacji przywraca konfigurację strony do stanu wyjściowego.

Alternatywa: Redirection

Wtyczka Redirection jest znana jako menedżer przekierowań, ale potrafi też dodawać nagłówki HTTP. Po instalacji i podstawowej konfiguracji proszę przejść do sekcji Site → Headers, interfejs pozwala wpisać dowolne pary „nagłówek: wartość".

Ta opcja sprawdzi się, jeśli ma Pan/Pani już Redirection do zarządzania linkami i nie chce dodawać kolejnej wtyczki. Ale dedykowana wtyczka do nagłówków daje więcej kontroli i wstępnie ustawione wartości.

Na wideo: poglądowa demonstracja konfiguracji nagłówków przez wtyczkę Headers Security Advanced, od instalacji po sprawdzenie wyniku na securityheaders.com.

⁉️🤔 Często zadawane pytania

Co zrobić, jeśli po włączeniu nagłówków strona się zepsuła?

W pierwszej kolejności proszę sprawdzić nagłówek Content-Security-Policy, to on powoduje przeważającą większość awarii. Proszę wyłączyć CSP (lub przełączyć w tryb Report-Only) i sprawdzić stronę ponownie. Błąd 500 po edycji.htaccess: proszę sprawdzić składnię: zbędna spacja, niezamknięte cudzysłowy lub brak modułu mod_headers. Przez FTP proszę zmienić nazwę.htaccess, strona ożyje i będzie mógł Pan/mogła Pani spokojnie znaleźć błąd.

W 9 na 10 przypadków problemem jest właśnie CSP, a nie pozostałe nagłówki. X-Content-Type-Options, X-Frame-Options, HSTS i Referrer-Policy fizycznie nie mogą zepsuć strony, nie dotykają renderowania ani logiki PHP. Proszę zawsze zaczynać od nich.

Czy koniecznie trzeba używać wtyczki, czy można przez kod?

Można i trzeba przez kod, jeśli potrafi Pan/Pani edytować functions.php lub.htaccess. Bezpośrednie ustawienie nagłówków przez konfigurację serwera działa szybciej niż wtyczka, nie ma warstwy PHP. Ale wtyczka jest wygodniejsza dla tych, którzy nie chcą ingerować w kod, i daje wizualny interfejs z ustawieniami wstępnymi dla każdego nagłówka.

Na naszych stronach testowych używamy obu podejść: na produkcji.htaccess (mniej punktów awarii), na stronach klientów, gdzie hosting nie pozwala edytować konfiguracji, wtyczka. Wynik na securityheaders.com jest identyczny: A+ w obu przypadkach.

Czy trzeba konfigurować CSP, jeśli strona jest na WordPress?

Dla większości stron nie. CSP na WordPress wymaga unsafe-inline i unsafe-eval do działania Gutenberga i dziesiątek wtyczek, co redukuje efekt ochronny do symbolicznego. Pełnowartościowy CSP ma sens na wysoko obciążonych projektach z dedykowanym specjalistą ds. bezpieczeństwa, który będzie analizował każdy raport o naruszeniu. Dla wszystkich pozostałych 5 podstawowych nagłówków daje lwią część praktycznej ochrony.

Jak sprawdzić, czy nagłówki działają po instalacji?

Proszę otworzyć stronę w przeglądarce, uruchomić DevTools (F12) → zakładka Network → kliknąć na pierwsze żądanie do Pana/Pani domeny → sekcja Response Headers. Jeśli widzi Pan/Pani dodane nagłówki, wszystko działa. Do automatycznego sprawdzenia proszę użyć securityheaders.com, pokazuje ono nie tylko obecność, ale i poprawność wartości, a także końcową ocenę od A+ do F.

Co zrobić, jeśli hosting nie pozwala edytować.htaccess i nie ma dostępu do functions.php?

Proszę zainstalować Headers Security Advanced & HSTS WP przez panel administracyjny WordPress. Wtyczka wdraża nagłówki na poziomie PHP i nie wymaga edycji plików serwera. Działa to na każdym hostingu, na którym działa WordPress, od taniego shared po Managed WordPress.

Czy nagłówki HTTP wpływają na szybkość strony?

Praktycznie nie. Nagłówki to kilkadziesiąt bajtów tekstu w odpowiedzi serwera. Nie wykonują obliczeń, nie robią zapytań do bazy danych, nie obciążają procesora. Opóźnienie, które dodają, mierzy się w mikrosekundach. Jedyny wyjątek to CSP ze skomplikowaną białą listą setek domen: przeglądarka traci czas na parsowanie, ale nawet w tym przypadku wpływ na szybkość renderowania nie przekracza kilku milisekund.

Co ustawić i od czego zacząć

Nagłówki bezpieczeństwa HTTP to nie jednorazowa akcja „ustaw i zapomnij". To punkt wyjścia, który powinien być na każdej stronie domyślnie, jak certyfikat SSL.

Plan na dziś:

  • Proszę sprawdzić stronę na securityheaders.com. Jeśli ocena to D lub F, nie ma Pan/Pani nawet X-Content-Type-Options.

  • Proszę dodać 5 podstawowych nagłówków dowolnym z trzech powyższych sposobów. Jeśli strona na Apache, przez.htaccess (30 sekund). Nginx bez dostępu do konfiguracji, przez functions.php (2 minuty). Jeśli nie chce Pan/Pani kodu, wtyczka Headers Security Advanced (3 minuty z instalacją).

  • Proszę sprawdzić jeszcze raz stronę. Ocena powinna wzrosnąć do A lub A+.

  • CSP proszę odłożyć. Proszę wrócić do niego, gdy podstawowe nagłówki przepracują miesiąc bez problemów, a Pan/Pani będzie miał czas na testowanie przez Report-Only.

Jedna godzina i Pana/Pani strona na WordPress zyskuje warstwę ochrony, której nie ma przeważająca większość stron w internecie. Proszę zacząć od sprawdzenia już teraz.