Nagłówki bezpieczeństwa na stronie firmowej: CSP, HSTS, SRI i ochrona przed clickjackingiem

Andrzej Winnicki
16.01.2026

Strona firmowa to dziś nie tylko wizytówka, ale też punkt styku z leadami, płatnościami, formularzami i narzędziami analitycznymi. To oznacza jedno: nawet jeśli nie masz panelu logowania i nie przetwarzasz „wrażliwych” danych, Twoja strona nadal może stać się celem. Najczęstszy scenariusz nie wygląda jak hollywoodzki atak, tylko jak drobna wpadka: ktoś podmienia skrypt zewnętrzny, wstrzykuje złośliwy kod przez podatny komponent, albo nakłada na Twoją stronę niewidoczną „ramkę”, by wyłudzać kliknięcia.

„Nagłówki bezpieczeństwa” to proste ustawienia po stronie serwera (lub CDN), które mówią przeglądarce: jak ma traktować Twoją stronę i czego ma nie pozwolić zrobić. Dobre wdrożenie potrafi:

  • ograniczyć skutki XSS (wstrzyknięcia kodu w przeglądarce),
  • wymusić HTTPS i zmniejszyć ryzyko przechwycenia ruchu,
  • zabezpieczyć korzystanie z zasobów zewnętrznych (np. z CDN),
  • zablokować clickjacking (czyli „kradzież kliknięć” przez osadzanie strony w ramce).

W tym artykule dostajesz praktyczny zestaw: CSP, HSTS, SRI i ochrona przed clickjackingiem, plus kilka nagłówków „wspierających”, które zwykle warto dorzucić, gdy już robisz porządek.

Zanim zaczniesz: najczęstsze błędy i zasada bezpiecznego wdrożenia

Największy błąd to włączenie wszystkiego „na raz” i „na sztywno”. CSP i HSTS potrafią unieruchomić część serwisu, jeśli masz stare integracje, niestandardowe skrypty lub zasoby ładowane z różnych domen. Dlatego wdrażaj etapami:

  • Najpierw inwentaryzacja: jakie domeny dostarczają skrypty, style, fonty, iframy, obrazki, API.
  • Najpierw tryb obserwacji: CSP w trybie Report-Only (jeśli masz gdzie zbierać raporty).
  • Najpierw wersja „umiarkowana”: HSTS bez preload i bez includeSubDomains, dopóki nie masz pełnej pewności.
  • Na końcu zaostrzenie reguł: usuwanie wyjątków, porządkowanie inline, przejście na nonce/hash w CSP.

Druga zasada: bezpieczeństwo nagłówkami to nie plaster na złamaną nogę. Jeśli masz realną podatność (np. wtyczkę w CMS), nagłówki ograniczą skutki, ale nie zastąpią aktualizacji i napraw. Traktuj je jako pasy bezpieczeństwa: nie powstrzymają wypadku, ale potrafią uratować sytuację.

CSP: Content Security Policy, czyli „skąd wolno ładować kod”

Content-Security-Policy to najważniejszy nagłówek w tej układance, bo działa bezpośrednio na ryzyko XSS. W skrócie: przeglądarka dostaje listę dozwolonych źródeł dla skryptów, styli, obrazów, fontów, połączeń do API, ramek itd. Jeśli w stronie pojawi się „obcy” skrypt albo próba wstrzyknięcia inline, CSP może to zablokować.

Dlaczego CSP jest trudny? Bo wiele stron marketingowych ma:

  • kilka narzędzi analitycznych naraz,
  • tagi reklamowe i integracje zewnętrzne,
  • inline skrypty i style generowane przez CMS,
  • zasoby z CDN, fonty z zewnętrznych domen, osadzenia wideo.

Najprostszy (i najbezpieczniejszy) kierunek to ograniczanie skryptów do własnej domeny, a integracje zewnętrzne dopisywać świadomie. Minimalna baza, od której często warto zacząć, wygląda tak (przykład ideowy, a nie „wklejka w ciemno”):

default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none';

Co te dyrektywy robią w praktyce?

  • default-src 'self' ustawia domyślne źródło na Twoją domenę.
  • base-uri 'self' utrudnia manipulacje tagiem , które mogą zmieniać rozwiązywanie adresów zasobów.
  • object-src 'none' blokuje stare wtyczki typu Flash/Silverlight (dziś rzadko, ale po co ryzykować).
  • frame-ancestors 'none' (to też ochrona przed clickjackingiem) mówi, że Twojej strony nie wolno osadzać w ramce.

Dalej zwykle musisz doprecyzować:

  • script-src (najważniejsze): skąd wolno ładować JS oraz czy dopuszczasz inline.
  • style-src: skąd wolno ładować CSS (tu często pojawia się problem inline styli).
  • img-src: obrazy (często potrzebne data: dla SVG inline lub małych ikon, ale warto to przemyśleć).
  • connect-src: połączenia XHR/fetch/WebSocket do analityki, API, pikseli.
  • frame-src: jeśli osadzasz np. wideo, mapy, formularze zewnętrzne.

W praktyce, jeśli masz dużo inline skryptów, kuszące jest dodanie 'unsafe-inline'. To działa, ale osłabia sens CSP. Lepsza droga to przejście na nonce/hashy. Nonce to losowy token generowany per odpowiedź HTML i dopinany do skryptów, które mają mieć prawo się wykonać. Hash to „odcisk” treści skryptu inline. Wymaga to pracy, ale daje realną ochronę.

Wdrożenie etapowe CSP bez bólu:

  • Start: CSP w trybie raportowania (jeśli masz endpoint na raporty), albo start z luźniejszą polityką i stopniowe zaostrzanie.
  • Wyczyść „dzikie” zasoby: usuń nieużywane tagi, stare integracje, duplikaty pikseli.
  • Uporządkuj inline: przenieś JS/CSS do plików, a to co musi zostać inline zabezpiecz nonce lub hash.
  • Zablokuj „to, czego nie potrzebujesz”: np. object-src 'none', ogranicz frame-src, dopilnuj base-uri.

HSTS: wymuszenie HTTPS bez „ale”

Strict-Transport-Security (HSTS) mówi przeglądarce: „od teraz łącz się z tą domeną tylko przez HTTPS”. To redukuje ryzyko ataków typu downgrade (przestawianie na HTTP), oraz ogranicza możliwość przechwycenia ruchu w niektórych scenariuszach sieciowych.

Przykładowy nagłówek:

Strict-Transport-Security: max-age=31536000

max-age to czas w sekundach, przez jaki przeglądarka ma pamiętać wymuszenie HTTPS. Często zaczyna się od krótszego okresu (np. tydzień), a potem wydłuża. Dwie opcje, które wyglądają niewinnie, ale wymagają żelaznej pewności:

  • includeSubDomains – obejmuje też subdomeny. Jeśli masz jakąkolwiek subdomenę, która nie działa na HTTPS, możesz sobie narobić problemów.
  • preload – wpis na listę preload w przeglądarkach. To bardzo mocne i trudne do odkręcenia, więc wchodzi w grę dopiero, gdy masz pełną kontrolę nad domeną i subdomenami.

Wersja „dojrzała”, gdy masz pewność co do całej domeny:

Strict-Transport-Security: max-age=31536000; includeSubDomains

HSTS jest szczególnie ważne, jeśli na stronie są formularze, logowanie, integracje płatności albo cokolwiek, co nie powinno „przypadkiem” polecieć po HTTP.

SRI: Subresource Integrity, czyli kontrola treści zasobów zewnętrznych

SRI to mechanizm po stronie HTML, który pozwala powiedzieć przeglądarce: „ten plik JS/CSS musi mieć dokładnie taką sumę kontrolną, inaczej go nie ładuj”. Chroni to przed scenariuszem, w którym zewnętrzny zasób (np. z CDN) zostaje podmieniony.

To nie jest nagłówek HTTP, tylko atrybuty w tagach

Kiedy SRI ma największy sens?

  • Gdy ładujesz biblioteki z CDN i zależy Ci na odporności na podmiany.
  • Gdy wersjonujesz zasoby (np. pliki z hashem w nazwie), a nie podmieniasz ich „pod tym samym URL-em”.
  • Gdy masz kontrolę nad tym, kiedy i jak aktualizujesz biblioteki.

Kiedy SRI może przeszkadzać?

  • Gdy dostawca zasobu potrafi zmienić treść pod tym samym adresem (np. „latest”). Wtedy hash przestanie pasować i zasób się nie załaduje.
  • Gdy masz automatyczne minifikacje/transformacje po drodze, które zmieniają treść pliku.

Najlepsza praktyka: jeśli już korzystasz z CDN, korzystaj z konkretnych wersji bibliotek, a nie „pływających” odnośników. Dzięki temu SRI jest przewidywalne.

Clickjacking: jak zablokować „kradzież kliknięć”

Clickjacking polega na tym, że atakujący osadza Twoją stronę w niewidocznej (lub sprytnie przyciętej) ramce i nakłada na nią własne elementy. Użytkownik myśli, że klika coś u atakującego, a w rzeczywistości klika przyciski na Twojej stronie. Na stronach marketingowych brzmi to abstrakcyjnie, ale jeśli masz jakiekolwiek formularze, potwierdzenia, akcje typu „wyślij”, „zamów”, „zapisz się”, to robi się realne.

Najlepsza ochrona to dyrektywa CSP:

Content-Security-Policy: frame-ancestors 'none'

Jeśli musisz pozwolić na osadzenie strony (np. landing w partnerskim portalu), możesz wpuścić konkretne domeny:

frame-ancestors 'self' https://partner.example

Dodatkowo istnieje starszy nagłówek:

X-Frame-Options: DENY albo SAMEORIGIN

W wielu wdrożeniach stosuje się oba: CSP jako główna kontrola i X-Frame-Options jako „backup” dla starszych przeglądarek. Najważniejsze: nie zostawiaj tego domyślnie otwartego, jeśli nie masz powodu.

Nagłówki wspierające, które zwykle warto dorzucić

Skoro już porządkujesz nagłówki, dorzucenie kilku kolejnych często daje szybkie korzyści małym kosztem:

  • X-Content-Type-Options: nosniff – utrudnia „zgadywanie” typu pliku przez przeglądarkę, co bywa wykorzystywane w atakach.
  • Referrer-Policy – kontroluje, ile informacji o źródle żądania wysyłasz dalej (pomaga ograniczyć wycieki URL-i z parametrami).
  • Permissions-Policy – pozwala ograniczyć dostęp do funkcji przeglądarki (np. kamera, mikrofon, geolokalizacja), jeśli Twoja strona ich nie potrzebuje.

Uwaga praktyczna: nie chodzi o to, by włączyć „wszystko”, tylko by świadomie ograniczyć powierzchnię ataku. Jeśli Twoja strona nie korzysta z kamery i geolokalizacji, to po co pozostawiać te furtki otwarte.

Gdzie to wdrożyć: serwer, CMS czy CDN

Nagłówki możesz ustawić na kilka sposobów:

  • Na serwerze WWW (np. konfiguracja Nginx/Apache).
  • Na warstwie aplikacji (np. middleware, plugin bezpieczeństwa w CMS).
  • Na CDN/WAF (np. reguły nagłówków na brzegu, co bywa najprostsze, jeśli nie chcesz dotykać serwera).

Najważniejsze: trzymaj jedną „prawdę”. Jeśli część nagłówków ustawisz w CMS, a część w CDN, łatwo o konflikt lub duplikaty. Ustal miejsce docelowe i pilnuj spójności. W praktyce często wygrywa CDN, bo ułatwia szybkie poprawki, a CSP/HSTS da się tam wdrażać stopniowo.

Testy i kontrola jakości: jak nie zrobić sobie krzywdy

Po wdrożeniu nie kończysz pracy. Warto mieć prostą checklistę testów:

  • Sprawdź stronę na desktop i mobile, szczególnie formularze, popupy, czaty, integracje analityczne.
  • Zweryfikuj, czy nie blokujesz krytycznych zasobów (CSP potrafi „po cichu” wyciąć część skryptów).
  • Sprawdź subdomeny przed włączeniem includeSubDomains w HSTS.
  • Jeśli używasz SRI, upewnij się, że aktualizacje bibliotek mają kontrolowany proces.
  • Monitoruj błędy w konsoli przeglądarki i w narzędziach analitycznych (nagłówki mogą zmienić zachowanie tagów).

Dobra praktyka dla CSP: zostaw sobie czas na „odchudzanie wyjątków”. Na początku prawie zawsze dopisujesz kilka domen „bo inaczej coś nie działa”. Potem warto wrócić i zdecydować: czy ta integracja jest naprawdę potrzebna, czy tylko „została po starych kampaniach”. CSP potrafi być świetnym narzędziem porządkującym marketingowy bałagan.

Podsumowanie: minimum sensownego bezpieczeństwa dla strony marketingowej

Jeśli masz zrobić tylko cztery rzeczy, zrób te:

  • Włącz CSP i doprowadź ją do sensownego poziomu (docelowo bez 'unsafe-inline' dla skryptów).
  • Włącz HSTS etapami i nie pchaj się w preload, dopóki nie masz 100% pewności.
  • Dodaj ochronę przed clickjackingiem przez frame-ancestors (i ewentualnie X-Frame-Options jako wsparcie).
  • Jeśli używasz CDN dla bibliotek, rozważ SRI i wersjonowanie zasobów.

To nie są „fajerwerki dla korporacji”. To podstawy, które na zwykłej stronie firmowej potrafią zapobiec bardzo kosztownym problemom wizerunkowym.

Źródła

  • https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP – dokumentacja MDN o Content Security Policy, dyrektywach i przykładach wdrożeń.
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security – dokumentacja MDN o HSTS, parametrach max-age/includeSubDomains/preload i konsekwencjach.
  • https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity – dokumentacja MDN o SRI, atrybucie integrity i praktycznych ograniczeniach.
  • https://owasp.org/www-community/attacks/Clickjacking – opis clickjackingu w OWASP wraz z metodami obrony (CSP frame-ancestors, X-Frame-Options).
  • https://web.dev/security-headers/ – omówienie nagłówków bezpieczeństwa w web.dev, kontekst wdrożeniowy i wskazówki praktyczne.
Zgłoś swój pomysł na artykuł

Więcej w tym dziale Zobacz wszystkie