Bezpieczeństwo to nie tylko certyfikat SSL

Wdrożenie certyfikatu SSL i przekierowanie na HTTPS to dopiero początek zabezpieczania strony internetowej. Sam certyfikat chroni dane w transmisji, ale nie zabezpiecza przed wieloma typami ataków — clickjacking, cross-site scripting (XSS), sniffing typu MIME czy downgrade do HTTP. Do tego służą nagłówki bezpieczeństwa HTTP — instrukcje, które serwer wysyła przeglądarce, informując ją o zasadach bezpieczeństwa obowiązujących na danej stronie.

Konfiguracja tych nagłówków jest prosta i nie wymaga zmian w kodzie aplikacji — wystarczy kilka linii w konfiguracji serwera. Przyjrzyjmy się najważniejszym z nich.

HSTS — Strict-Transport-Security

HSTS to prawdopodobnie najważniejszy nagłówek bezpieczeństwa. Informuje przeglądarkę, że strona powinna być zawsze ładowana przez HTTPS — nawet jeśli użytkownik wpisze adres z http:// lub kliknie link HTTP.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

Parametry:

  • max-age=31536000 — przeglądarka będzie pamiętać to ustawienie przez rok (31 536 000 sekund)
  • includeSubDomains — zasada obejmuje wszystkie subdomeny
  • preload — pozwala zgłosić domenę do listy HSTS preload, wbudowanej w przeglądarki

Dlaczego to ważne? Bez HSTS pierwsze połączenie z Twoją stroną może przebiegać przez HTTP (zanim nastąpi przekierowanie na HTTPS). W tym krótkim oknie atakujący w sieci lokalnej (np. w kawiarni z publicznym Wi-Fi) może przechwycić ruch — to tzw. atak SSL stripping. HSTS eliminuje ten wektor ataku.

Uwaga: przed włączeniem HSTS upewnij się, że HTTPS działa poprawnie na wszystkich stronach i subdomenach. Po aktywacji HSTS cofnięcie jest trudne — przeglądarki będą odmawiać połączenia HTTP przez cały okres max-age.

Content-Security-Policy (CSP)

CSP to najpotężniejszy, ale i najbardziej skomplikowany nagłówek bezpieczeństwa. Definiuje, z jakich źródeł przeglądarka może ładować zasoby — skrypty, style, obrazy, czcionki i inne.

Przykład restrykcyjnej polityki CSP:

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" always;

Co oznaczają poszczególne dyrektywy:

  • default-src 'self' — domyślnie pozwalaj na zasoby tylko z własnej domeny
  • script-src 'self' — JavaScript tylko z własnego serwera (blokuje inline scripts i zewnętrzne źródła)
  • style-src 'self' 'unsafe-inline' — CSS z własnego serwera i style inline (niestety wiele stron ich wymaga)
  • img-src 'self' data: — obrazy z własnego serwera i jako data URI
  • frame-ancestors 'none' — strona nie może być osadzona w ramce (zastępuje X-Frame-Options)
  • form-action 'self' — formularze mogą być wysyłane tylko do własnej domeny

Wdrażanie CSP warto zacząć od trybu raportowania:

add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report" always;

W tym trybie przeglądarka nie blokuje zasobów, a jedynie raportuje naruszenia. Pozwala to dostroić politykę przed wprowadzeniem restrykcji.

X-Frame-Options

Ten nagłówek chroni przed atakami typu clickjacking — techniką polegającą na osadzeniu Twojej strony w niewidocznej ramce (iframe) na stronie atakującego, aby nakłonić użytkownika do kliknięcia w elementy Twojej strony bez jego wiedzy.

add_header X-Frame-Options "DENY" always;

Opcje:

  • DENY — strona nie może być nigdy wyświetlana w iframe
  • SAMEORIGIN — strona może być wyświetlana w iframe tylko na tej samej domenie

Jeśli używasz dyrektywy frame-ancestors w CSP, X-Frame-Options jest technicznie zbędny. Jednak warto go zostawić dla kompatybilności ze starszymi przeglądarkami.

X-Content-Type-Options

Zapobiega MIME type sniffing — technice, w której przeglądarka próbuje „odgadnąć" typ pliku na podstawie jego zawartości, ignorując nagłówek Content-Type serwera. To może prowadzić do wykonania złośliwego kodu ukrytego np. w pliku obrazu.

add_header X-Content-Type-Options "nosniff" always;

Jedyna dozwolona wartość to nosniff. Ten nagłówek jest prosty, bezpieczny i nie ma powodu, żeby go nie włączyć.

Referrer-Policy

Kontroluje, ile informacji o adresie URL jest przekazywane w nagłówku Referer przy nawigacji na zewnętrzne strony.

add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Ta wartość oznacza: przy nawigacji w obrębie tej samej domeny przesyłaj pełny adres URL; przy nawigacji na zewnętrzne domeny przesyłaj tylko origin (np. https://www.linwork.pl bez ścieżki). To chroni prywatność użytkowników, nie psując jednocześnie analityki.

Permissions-Policy

Dawniej znany jako Feature-Policy. Kontroluje, które API przeglądarki (kamera, mikrofon, geolokalizacja, płatności) mogą być używane na stronie.

add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;

Puste nawiasy oznaczają całkowite zablokowanie danej funkcji. Dla typowej strony firmowej nie ma powodu, aby pozwalać na dostęp do kamery czy mikrofonu.

Kompletna konfiguracja Nginx

Oto pełna konfiguracja nagłówków bezpieczeństwa, którą stosujemy w naszych projektach:

# Bezpieczeństwo transportu
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Ochrona przed XSS i injection
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" always;

# Ochrona przed clickjacking
add_header X-Frame-Options "DENY" always;

# Ochrona przed MIME sniffing
add_header X-Content-Type-Options "nosniff" always;

# Polityka referrera
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Kontrola uprawnień
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;

Wszystkie nagłówki używają dyrektywy always, co oznacza, że będą wysyłane nawet dla odpowiedzi z kodem błędu (403, 404, 500).

Jak sprawdzić konfigurację

Po wdrożeniu nagłówków warto je zweryfikować:

  • securityheaders.com — darmowe narzędzie, które skanuje stronę i przyznaje ocenę A-F
  • Observatory by Mozilla — bardziej szczegółowa analiza, obejmująca również inne aspekty bezpieczeństwa
  • Narzędzia deweloperskie przeglądarki — zakładka Network, nagłówki odpowiedzi dowolnego żądania

Celuj w ocenę A+ na securityheaders.com. Jest to osiągalne dla każdej strony i nie wymaga żadnych kompromisów w funkcjonalności.

Częste błędy

Na koniec lista najczęstszych błędów, które widzimy podczas audytów:

  • Brak HSTS mimo wdrożenia HTTPS — przekierowanie 301 nie chroni przed SSL stripping
  • Zbyt permisywny CSPscript-src 'unsafe-inline' 'unsafe-eval' w praktyce wyłącza ochronę CSP
  • Nagłówki tylko na stronie głównej — upewnij się, że konfiguracja obejmuje wszystkie ścieżki
  • Brak dyrektywy always w Nginx — bez niej nagłówki nie są wysyłane dla odpowiedzi błędów

Wdrożenie kompletnych nagłówków bezpieczeństwa to kilkanaście minut pracy, a efekt to znacznie wyższy poziom ochrony użytkowników Twojej strony. Jeśli potrzebujesz pomocy z konfiguracją — skontaktuj się z nami.