DNS RobotDNS Propagation Checker
GłównaDNSWHOISIPSSL
DNS RobotDNS Propagation Checker

Checker propagacji DNS nowej generacji

Polityka PrywatnościRegulaminO nasBlogKontakt

Narzędzia DNS

Wyszukiwanie DNSTest Szybkości DNSDomena na IPWyszukiwanie NSWyszukiwanie MXZobacz wszystko

Narzędzia E-mail

Sprawdzanie Rekordu SPFSprawdzanie DMARCSprawdzanie DKIMTest SMTPAnaliza Nagłówków E-mailZobacz wszystko

Narzędzia Stron WWW

Wyszukiwanie WHOISSprawdzanie hostinguDostępność DomenyWyszukiwarka SubdomenWykrywanie CMSZobacz wszystko

Narzędzia Sieciowe

Narzędzie PingTracerouteSprawdzanie PortówSprawdzanie Nagłówków HTTPSprawdzanie Certyfikatu SSLZobacz wszystko

Narzędzia IP

Wyszukiwanie IPJaki Jest Mój IPSprawdzanie Czarnej Listy IPIP na HostnameWyszukiwanie ASNZobacz wszystko

Narzędzia Pomocnicze

Skaner QR CodeGenerator QR CodeUPI QR Code GeneratorWiFi QR Code GeneratorTłumacz Kodu Morse'aZobacz wszystko
© 2026 DNS Robot. Opracowane przez: ❤ Shaik Brothers
Wszystkie systemy działają
Made with
Strona główna/Blog/Bezpieczeństwo strony internetowej: 6 warstw ochrony (2026)

Bezpieczeństwo strony internetowej: 6 warstw ochrony (2026)

Shaik Vahid29 wrz 202630 min czytania
Bezpieczeństwo strony internetowej jako sześć warstw: domena i DNS, TLS, nagłówki HTTP, aplikacja, zależności, serwer
Bezpieczeństwo strony internetowej jako sześć warstw: domena i DNS, TLS, nagłówki HTTP, aplikacja, zależności, serwer

Kluczowy wniosek

Bezpieczeństwo strony internetowej buduje się warstwami: zabezpiecz domenę i DNS (registrar lock, DNSSEC, CAA), wymuś nowoczesne TLS z HSTS, wysyłaj restrykcyjny zestaw nagłówków bezpieczeństwa HTTP, hashuj hasła algorytmem Argon2id i chroń logowanie za pomocą MFA oraz limitów żądań, waliduj dane wejściowe i egzekwuj kontrolę dostępu po stronie serwera, przypinaj wersje zależności i regularnie je audytuj, zamknij każdy port, na którym niczego nie udostępniasz, i zbieraj logi wystarczające do wykrycia włamania. Każda praktyka poniżej zawiera dokładną konfigurację i darmowy sposób sprawdzenia, czy naprawdę działa — bo zabezpieczenie, którego nie przetestowano, to zabezpieczenie, którego nie masz.

Advertisement

Czym właściwie jest bezpieczeństwo strony internetowej

Bezpieczeństwo strony internetowej to w praktyce zestaw zabezpieczeń, które chronią stronę lub aplikację webową przed przejęciem, podmianą treści, wykorzystaniem jej do atakowania własnych użytkowników albo cichym wyciekiem danych. Nie jest to jeden produkt ani jedno ustawienie. To cały stos decyzji, który zaczyna się u rejestratora domeny, a dalej obejmuje DNS, TLS, nagłówki HTTP wysyłane przez serwer, kod obsługujący logowanie i dane wejściowe, zewnętrzne pakiety, na których budujesz aplikację, sam serwer, a na końcu logi, które powiedzą Ci, że coś poszło nie tak.

Warto myśleć warstwami, bo tak właśnie myślą atakujący. Raport Verizon 2026 Data Breach Investigations Report wykazał, że 31% naruszeń zaczyna się dziś od wykorzystania podatności w oprogramowaniu — po raz pierwszy wyprzedziło to skradzione dane logowania jako najczęstszą drogę wejścia — oraz że 48% wszystkich naruszeń wiąże się z ransomware. Wystarczy jedna brakująca poprawka, jeden wyciekły klucz API albo panel administracyjny bez limitowania żądań. Żadne z zabezpieczeń opisanych w tym przewodniku nie jest egzotyczne; włamania zdarzają się zwykle na stronach, które dopracowywały jedną warstwę, a pominęły podstawy na innej.

Przewodnik jest uporządkowany od zewnątrz do środka. Przy każdej praktyce znajdziesz powód, dla którego jest ważna, dokładną konfigurację i sposób weryfikacji za pomocą polecenia lub darmowego narzędzia — bo najczęstszy problem, jaki widzimy przy sprawdzaniu nagłówków HTTP i sprawdzaniu certyfikatów SSL, to nie zła decyzja, lecz ustawienie, które ktoś uważał za włączone i nigdy tego nie potwierdził.

Uwaga

Jeśli masz tylko godzinę: włącz registrar lock i MFA u rejestratora, wymuś HTTPS z HSTS, dodaj nagłówki bezpieczeństwa z tabeli w warstwie 3, hashuj hasła algorytmem Argon2id, zaktualizuj każdą zależność ze znanym CVE i zamknij wszystkie porty poza 80 i 443. To zamyka drogi wejścia, od których zaczyna się zdecydowana większość rzeczywistych włamań na strony internetowe.

Stos bezpieczeństwa strony: sześć warstw do ochrony

Każdy atak na stronę internetową trafia w jedną z sześciu warstw. Poniższa tabela to mapa reszty przewodnika: co znajduje się na każdej warstwie, jak zwykle jest atakowane i które darmowe narzędzie potwierdzi, że Twoja ochrona faktycznie działa.

WarstwaCo robią tu atakującyKluczowe praktykiJak sprawdzić
1. Domena i DNSPrzejmują domenę, zmieniają serwery nazw, przejmują porzucone subdomeny, uzyskują nieuprawnione certyfikatyRegistrar lock, MFA, DNSSEC, CAA, audyt nieaktualnych rekordówWyszukiwanie WHOIS, Wyszukiwanie DNS, Wyszukiwarka Subdomen
2. Transport (TLS)Wymuszają powrót do HTTP, usuwają szyfrowanie, wykorzystują stare szyfry i wygasłe certyfikatyTLS 1.2+, HSTS z preload, automatyczne odnawianieSprawdzanie Certyfikatu SSL
3. Nagłówki HTTPWstrzykują skrypty (XSS), osadzają stronę w ramce do clickjackingu, wykorzystują zgadywanie typów treści, wyciągają adresy z nagłówka RefererCSP, frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicySprawdzanie Nagłówków HTTP
4. AplikacjaCredential stuffing, injection, błędy kontroli dostępu, CSRF, niebezpieczne przesyłanie plikówArgon2id + MFA + limity żądań, zapytania parametryzowane, autoryzacja po stronie serwera, ciasteczka SameSitePrzegląd kodu, OWASP ZAP, Test Siły Hasła
5. ZależnościZatrute pakiety, znane CVE w bibliotekach, przejęte potoki CILockfile, audyty, przypięte wersje, SBOM, tokeny z minimalnymi uprawnieniaminpm audit, Dependabot, Trivy
6. Serwer i utrzymanieOtwarte porty, domyślne hasła, brak poprawek, brak kopii zapasowych, brak logówFirewall, SSH tylko z kluczami, regularne łatanie, kopie zapasowe 3-2-1, centralne gromadzenie logówSprawdzanie Portów, Sprawdzanie Czarnej Listy IP, Sprawdzanie Kondycji Domeny

Wskazówka

Pracuj od góry do dołu. Warstwy 1–3 to konfiguracja, którą skończysz w jedno popołudnie, a chroni ona od razu każdą podstronę serwisu. Warstwy 4–6 to stałe nawyki, które muszą stać się częścią code review i procesu wdrożeń.

Advertisement

Warstwa 1: zabezpiecz domenę i DNS

Wszystko inne w tym przewodniku zakłada, że nadal kontrolujesz swoją domenę. Jeśli atakujący zaloguje się na Twoje konto u rejestratora albo zmieni serwery nazw, może skierować Twój ruch dokądkolwiek, uzyskać ważny certyfikat na Twoją domenę i czytać każdy e-mail wysłany do Ciebie — a kod Twojej aplikacji nawet się nie uruchomi. Dlatego bezpieczeństwo domeny i DNS to pierwsza z dobrych praktyk bezpieczeństwa stron i niemal w całości sprowadza się do konfiguracji.

Zacznij od wyszukiwania WHOIS dla własnej domeny i potwierdź trzy rzeczy: kody statusu zawierają clientTransferProhibited, data wygaśnięcia jest odległa o ponad rok, a rejestrator to firma, w której naprawdę masz konto. Zaskakująco często domena firmy wisi na koncie byłego podwykonawcy. Nasz przewodnik po WHOIS wyjaśnia każdy kod statusu, jaki zobaczysz.

Registrar lock, MFA i alerty o wygaśnięciu

Włącz registrar lock (nazywany też blokadą transferu), aby domeny nie dało się przenieść do innego rejestratora, dopóki jej wyraźnie nie odblokujesz, i włącz uwierzytelnianie wieloskładnikowe (MFA) na samym koncie u rejestratora. Konta u rejestratorów to ulubiony cel phishingu właśnie dlatego, że jedno logowanie kontroluje wszystko, co od niego zależy. Tam, gdzie rejestrator na to pozwala, używaj klucza sprzętowego lub aplikacji uwierzytelniającej zamiast SMS-ów.

Ustaw automatyczne odnawianie domeny z metodą płatności, która nie wygaśnie, a mimo to dodaj przypomnienie w kalendarzu 60 dni przed datą wygaśnięcia. Wygasłe domeny są przechwytywane przez usługi drop-catch w ciągu kilku godzin, a nowy właściciel przejmuje Twoją pocztę, Twój ruch i wszystkie logowania OAuth, które ufają Twojej domenie.

  • Registry lock (ręczna blokada na poziomie rejestru, zdejmowana poza zwykłym panelem) jest warta dodatkowej opłaty w przypadku domeny, od której zależy biznes; uniemożliwia zmianę serwerów nazw nawet z przejętego konta u rejestratora.

  • Rozdziel role. Osoba, która płaci za domenę, konto, na którym domena jest zarejestrowana, i dostawca DNS powinny być udokumentowane i nie mogą być powiązane ze skrzynką pocztową jednego pracownika.

  • Włącz ochronę prywatności WHOIS, aby Twoje dane kontaktowe nie stały się mapą dla phisherów, i podaj na koncie monitorowany adres funkcyjny, np. domains@.

Podpisz strefę za pomocą DNSSEC

DNSSEC podpisuje strefę DNS, dzięki czemu resolver może wykryć sfałszowane odpowiedzi. Bez niego atakujący, który zatruje pamięć podręczną resolvera, może skierować Twoich odwiedzających na fałszywy serwer, a przeglądarka nadal będzie pokazywać nazwę Twojej domeny. Większość zarządzanych dostawców DNS (Cloudflare, Route 53, Google Cloud DNS i wielu rejestratorów) włącza go jednym przełącznikiem; jedynym ręcznym krokiem jest opublikowanie rekordu DS u rejestratora. Sprawdź go poleceniem dig albo testem DNSSEC w Sprawdzaniu Kondycji Domeny:

bash
dig +dnssec +short yourdomain.com A
# A signed zone returns the record AND an RRSIG line:
# 203.0.113.10
# A 13 2 3600 20261015000000 20260924000000 34505 yourdomain.com. Kx3f...==

dig +short yourdomain.com DS
# A DS record at the parent zone proves the chain of trust is complete
# 34505 13 2 6A1B...C9

Ogranicz wystawianie certyfikatów rekordem CAA

Rekord CAA (RFC 8659) informuje urzędy certyfikacji (CA), które z nich mogą wystawiać certyfikaty dla Twojej domeny. Każdy publiczny CA musi go sprawdzić przed wystawieniem certyfikatu, więc rekord CAA zamyka drogę atakującemu, który oszukał walidację domeny w innym CA. Trzy rekordy obejmują typowe przypadki: kto może wystawiać certyfikaty, kto może wystawiać certyfikaty wildcard i dokąd zgłaszać odrzucone żądania:

dns
yourdomain.com.  CAA 0 issue "letsencrypt.org"
yourdomain.com.  CAA 0 issuewild ";"
yourdomain.com.  CAA 0 iodef "mailto:security@yourdomain.com"

Ostrzeżenie

Zanim dodasz CAA, spisz wszystkie CA, które obecnie wystawiają Ci certyfikaty, łącznie z tym, z którego korzysta Twój CDN lub panel hostingowy (Cloudflare rotuje między kilkoma CA; wielu hostingodawców używa Sectigo lub Let's Encrypt). Rekord CAA, który pomija Twój faktyczny CA, po cichu zablokuje następne odnowienie. Najpierw sprawdź obecnego wystawcę w Sprawdzaniu Certyfikatu SSL.

Audyt nieaktualnych rekordów: przejęcie subdomeny

Do przejęcia subdomeny (subdomain takeover) dochodzi, gdy rekord DNS wciąż wskazuje usługę, z której już nie korzystasz: CNAME do usuniętej strony GitHub Pages, aplikacji Azure, bucketu S3 albo hosta dostawcy SaaS. Każdy może zarejestrować porzucony cel i serwować treści pod old-app.yourdomain.com w Twoim imieniu, razem z ważnym certyfikatem. To jedno z najczęstszych zgłoszeń w programach bug bounty, bo nikt nie pamięta, że taki rekord w ogóle istnieje.

Sprawdź swoją domenę w Wyszukiwarce Subdomen, która odczytuje logi Certificate Transparency, dzięki czemu zobaczysz każdą nazwę hosta, dla której kiedykolwiek wystawiono certyfikat. Następnie rozwiąż każdą z nich za pomocą wyszukiwania DNS i usuń każdy rekord, którego cel zwraca NXDOMAIN albo stronę dostawcy z komunikatem „no such app”. Powtarzaj to co kwartał, a usuwanie rekordu DNS uczyń stałym elementem wyłączania każdej usługi.

Wskazówka

Certificate Transparency to także Twój system wczesnego ostrzegania: Cert Spotter i monitoring CT w Cloudflare mogą wysłać Ci e-mail za każdym razem, gdy jakikolwiek CA wystawi certyfikat dla Twojej domeny. Nieoczekiwany certyfikat bywa pierwszym widocznym sygnałem przejęcia DNS lub konta u rejestratora.

Warstwa 2: HTTPS i TLS skonfigurowane porządnie

HTTPS nie jest już dobrą praktyką, tylko absolutnym minimum — przeglądarki oznaczają zwykłe strony HTTP jako „Niezabezpieczona”. To, co wciąż odróżnia bezpieczną stronę od strony jedynie szyfrowanej, to akceptowane wersje TLS, to, czy do Twojej strony da się w ogóle dotrzeć przez HTTP, oraz to, czy odnawianie certyfikatów jest na tyle zautomatyzowane, by przetrwać skracanie ich ważności, które zaczęło się w marcu 2026 roku.

Advertisement

TLS 1.2 jako minimum, TLS 1.3 jako preferowany

TLS 1.0 i 1.1 zostały formalnie wycofane przez RFC 8996 w 2021 roku i żadna aktualna przeglądarka ich nie negocjuje. Wyłącz je na serwerze, preferuj TLS 1.3 (który eliminuje wszystkie znane słabe szyfry i kończy handshake w jednym przejściu tam i z powrotem) i zostaw TLS 1.2 wyłącznie z zestawami szyfrów AEAD, takimi jak ECDHE-ECDSA-AES128-GCM-SHA256 lub ECDHE-RSA-CHACHA20-POLY1305.

Podczas testu z zewnątrz liczą się dwie linie: wynegocjowany protokół oraz Verify return code: 0, co oznacza, że cały łańcuch certyfikatów przeszedł walidację. Brakujący certyfikat pośredni to najczęstsza przyczyna zgłoszeń typu „w Chrome działa, a w curl i na Androidzie nie”; nasz przewodnik po łańcuchu certyfikatów SSL pokazuje, jak to naprawić, a Sprawdzanie Certyfikatu SSL od razu oznacza niekompletny łańcuch. Oto test wykonany dla dnsrobot.net:

bash
echo | openssl s_client -connect dnsrobot.net:443 -servername dnsrobot.net 2>/dev/null \
  | grep -E 'Protocol|Cipher|Verify return'

# Protocol  : TLSv1.3
# Cipher    : TLS_AES_256_GCM_SHA384
# Verify return code: 0 (ok)

# Confirm the old versions are refused:
openssl s_client -connect dnsrobot.net:443 -tls1_1 2>&1 | grep -iE 'alert|no protocols'

Uwaga

Listy szyfrów to miejsce, w którym kopiowane konfiguracje najszybciej się starzeją. Zamiast pisać je ręcznie, wygeneruj aktualny zalecany blok konfiguracji serwera dla nginx, Apache, Caddy lub HAProxy w Mozilla SSL Configuration Generator i wybierz profil „Intermediate”, chyba że musisz obsługiwać bardzo stare klienty.

HSTS: przeglądarka już nigdy nie użyje HTTP

Samo przekierowanie z HTTP na HTTPS nie wystarczy. Pierwsze żądanie, jakie odwiedzający wysyła do http://yourdomain.com, wciąż wędruje otwartym tekstem, a atakujący w tej samej sieci może na nie odpowiedzieć, zanim zrobi to Twoje przekierowanie. HTTP Strict Transport Security (RFC 6797) rozwiązuje ten problem: gdy przeglądarka raz zobaczy ten nagłówek, każdy kolejny adres http:// Twojej domeny przepisuje na https://, zanim cokolwiek wyśle.

Ustaw max-age na co najmniej rok (31536000 sekund), dodaj includeSubDomains, gdy każda subdomena będzie obsługiwać HTTPS, a następnie zgłoś domenę na hstspreload.org, aby trafiła na listę wbudowaną na stałe w Chrome, Firefoksie, Safari i Edge. Preloading całkowicie zamyka lukę przy pierwszej wizycie. Sprawdź nagłówek w Sprawdzaniu Nagłówków HTTP, które ocenia HSTS w ramach oceny bezpieczeństwa w skali od A do F.

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

Ostrzeżenie

HSTS to drzwi, które otwierają się tylko w jedną stronę. Gdy includeSubDomains trafi na listę preload, każda subdomena, która nie potrafi obsłużyć poprawnego HTTPS — w tym narzędzia wewnętrzne i zapomniany host dev. — staje się w przeglądarkach nieosiągalna. Wdrażaj to etapami: max-age=300 przez tydzień, potem miesiąc, potem rok, i dopiero wtedy dodaj preload.

Certyfikaty 47-dniowe: zautomatyzuj odnawianie już teraz

Głosowanie SC-081 organizacji CA/Browser Forum etapami skraca maksymalny okres ważności każdego publicznego certyfikatu TLS. Pierwsze cięcie weszło w życie 15 marca 2026 roku, więc każdy certyfikat kupiony lub odnowiony dziś jest już ograniczony do 200 dni, a do 2029 roku certyfikat trzeba będzie wymieniać mniej więcej co sześć tygodni:

Data wejścia w życieMaksymalna ważność certyfikatuPonowne użycie walidacji domeny
Przed 15 marca 2026398 dni398 dni
15 marca 2026200 dni200 dni
15 marca 2027100 dni100 dni
15 marca 202947 dni10 dni

Ręczne odnawianie nie wytrzyma tego harmonogramu. Dobra praktyka to w pełni zautomatyzowane wystawianie certyfikatów przez ACME: Let's Encrypt lub Google Trust Services za pomocą certbota, acme.sh, Caddy albo automatycznych certyfikatów wbudowanych w Cloudflare, Vercel, Netlify i większość paneli hostingowych. Przetestuj ścieżkę odnawiania, zanim będzie potrzebna (certbot renew --dry-run w przypadku certbota); szukaj przede wszystkim rekordu CAA lub reguły firewalla dodanych od ostatniego odnowienia, które teraz blokują walidację. Niezależnie od narzędzia monitoruj datę wygaśnięcia także z zewnątrz: Sprawdzanie Certyfikatu SSL pokazuje liczbę pozostałych dni, a wygasły certyfikat zamienia każdą wizytę w pełnoekranowe ostrzeżenie przeglądarki.

Warstwa 3: nagłówki bezpieczeństwa HTTP

Nagłówki bezpieczeństwa to instrukcje, które serwer przekazuje przeglądarce: co wolno, a czego nie wolno jej robić z Twoimi stronami — które skrypty mogą się uruchomić, czy stronę można osadzić w ramce, czy przeglądarka może zgadywać typy treści i co ma przekazywać innym witrynom o tym, skąd przyszedł odwiedzający. Nic nie kosztują, działają od razu na każdej podstronie i blokują całe klasy ataków. To jednocześnie warstwa, którą większość witryn konfiguruje tylko częściowo poprawnie, i dlatego Sprawdzanie Nagłówków HTTP wystawia jej ocenę. Oto, co wysyła dnsrobot.net (tylko nagłówki bezpieczeństwa):

bash
curl -sI https://dnsrobot.net/ | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy'

strict-transport-security: max-age=31536000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self' ... https://*.googletagmanager.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(self), microphone=(), geolocation=(), payment=(), usb=()

Siedem nagłówków, które powinna wysyłać każda strona

To wartości, do których warto dążyć na typowej stronie. Pierwsze pięć wpływa na ocenę; ostatnie dwa to tanie dodatki, gdy pozostałe są już na miejscu.

NagłówekZalecana wartośćCo blokuje
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preloadDowngrade protokołu, kradzież ciasteczek przez HTTP
Content-Security-Policyscript-src oparty na nonce z 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'Cross-site scripting (XSS), wstrzykiwanie danych, clickjacking
X-Content-Type-OptionsnosniffMIME sniffing, który zamienia przesłany plik w wykonywalny skrypt
Referrer-Policystrict-origin-when-cross-originWyciek pełnych adresów URL (tokenów, wyszukiwanych fraz) do stron trzecich
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=()Ciche korzystanie z potężnych API przeglądarki przez zewnętrzne skrypty
X-Frame-OptionsDENY (starszy zamiennik dla frame-ancestors)Clickjacking w przeglądarkach bez CSP Level 2
Cross-Origin-Opener-Policysame-originAtaki między oknami przez window.opener

Content Security Policy bez psucia strony

Content Security Policy to najskuteczniejsza pojedyncza obrona przed XSS, bo blokuje wstrzyknięte skrypty nawet wtedy, gdy błąd umożliwiający wstrzyknięcie istnieje. Haczyk polega na tym, że restrykcyjna polityka psuje każdy skrypt inline i każdy zewnętrzny tag, o którym zapomniano. Nowoczesne podejście, zalecane przez Google i opisane w MDN, to polityka oparta na nonce: serwer generuje losowy nonce dla każdej odpowiedzi, dodaje go do każdego tagu script, który celowo renderuje, a przeglądarka odrzuca wszystko inne.

'strict-dynamic' sprawia, że taka polityka sprawdza się w praktyce: skrypt z nonce może ładować kolejne skrypty (analitykę, menedżery tagów, widżety) bez dodawania każdego z nich do listy dozwolonych, a tokeny https: i 'unsafe-inline' są ignorowane przez nowoczesne przeglądarki i służą jedynie jako fallback dla starych. Zacznij wdrożenie od Content-Security-Policy-Report-Only, obserwuj raporty o naruszeniach przez tydzień, a potem przełącz się na tryb egzekwowania. Frameworki takie jak Next.js, Rails i Django mają wbudowaną obsługę nonce; strony statyczne mogą zamiast tego użyć script-src opartego na hashach.

http
Content-Security-Policy:
  script-src 'nonce-r4nd0m1z3dV4lu3' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';
  frame-ancestors 'none';
  form-action 'self';
  report-to csp-endpoint

<!-- Only scripts carrying the nonce run; strict-dynamic lets them load their own dependencies -->
<script nonce="r4nd0m1z3dV4lu3" src="/app.js"></script>

Uwaga

Polityka oparta na liście dozwolonych źródeł, np. script-src 'self' https://cdn.example.com, jest lepsza niż nic, ale każdy endpoint JSONP lub stara biblioteka na dozwolonym hoście może posłużyć do jej obejścia. Jeśli jeszcze nie możesz używać nonce, ustaw przynajmniej object-src 'none' i base-uri 'none', co od razu zamyka dwie popularne metody obejścia.

Clickjacking: frame-ancestors i X-Frame-Options

Clickjacking polega na niewidocznym załadowaniu Twojej strony wewnątrz strony atakującego i nakłonieniu odwiedzającego do kliknięcia przycisku, którego nie widzi. frame-ancestors 'none' w CSP (lub 'self', jeśli osadzasz własne strony) zapobiega temu we wszystkich aktualnych przeglądarkach, a X-Frame-Options: DENY chroni starsze. Jeśli celowo udostępniasz widżet do osadzania, zwolnij z tej reguły tylko jego ścieżkę i tylko dla originów, które go potrzebują; nasz przewodnik po X-Frame-Options omawia dokładne reguły serwera i błędy „refused to connect”, na które trafisz podczas testów.

nosniff, Referrer-Policy, Permissions-Policy i COOP

X-Content-Type-Options: nosniff nie pozwala przeglądarce ignorować nagłówka Content-Type i zgadywać typu treści — a właśnie takie zgadywanie zamienia przesłany przez użytkownika „obrazek” zawierający HTML w wykonywalną stronę. Referrer-Policy: strict-origin-when-cross-origin (domyślna wartość w aktualnych przeglądarkach, ale ustaw ją jawnie) wysyła innym witrynom tylko Twój origin, więc tokeny resetu hasła i wyszukiwane frazy w adresach URL pozostają prywatne. Permissions-Policy wyłącza funkcje przeglądarki, z których nie korzystasz, więc przejęty zewnętrzny skrypt nie włączy kamery ani nie odczyta lokalizacji. Cross-Origin-Opener-Policy: same-origin zrywa powiązanie window.opener ze stronami, które otwierasz, co blokuje całą klasę ataków między oknami.

Liczą się też nagłówki, które należy usunąć: Server i X-Powered-By zdradzają skanerom podatności dokładne wersje oprogramowania, a X-XSS-Protection jest przestarzały i w starych przeglądarkach może powodować błędy, więc ustaw go na 0 albo całkowicie usuń. Wykrywanie CMS pokazuje, czego skaner dowiaduje się o Twoim stosie technologicznym z samych nagłówków.

Wskazówka

Ustawiaj nagłówki raz, na brzegu (CDN, reverse proxy lub middleware frameworka), zamiast na każdej stronie osobno. W Next.js jest to plik proxy lub middleware; w nginx blok add_header w kontekście server; w Apache Header always set. Następnie po każdym wdrożeniu ponownie uruchom Sprawdzanie Nagłówków HTTP, bo nowa wersja frameworka lub ustawienie CDN może po cichu usunąć któryś z nich.

Warstwa 4: uwierzytelnianie odporne na credential stuffing

Atakujący rzadko zgadują hasła po jednym. Odtwarzają miliardy par e-mail–hasło, które wyciekły z innych serwisów (credential stuffing), a resztę wyłudzają phishingiem. Dobre praktyki uwierzytelniania mają więc trzy części: przechowuj hasła tak, aby wyciek bazy danych nie oznaczał wycieku haseł, spraw, aby samo skradzione hasło było bezużyteczne, i spowolnij ataki brute force na tyle, żeby przestały mieć znaczenie. OWASP umieszcza Authentication Failures (błędy uwierzytelniania) na pozycji A07 w OWASP Top 10:2025.

Advertisement

Hashuj hasła za pomocą Argon2id lub bcrypt

Nigdy nie przechowuj hasła ani jego szybkiego hasha. MD5, SHA-1, a nawet SHA-256 zaprojektowano z myślą o szybkości, więc wyciekłą tabelę takich hashy można testować z prędkością miliardów prób na sekundę na jednym GPU. Używaj wolnej, pamięciochłonnej funkcji hashującej przeznaczonej do haseł z unikalną solą dla każdego hasła. OWASP Password Storage Cheat Sheet zaleca, w kolejności:

  • Argon2id z co najmniej 19 MiB pamięci, 2 iteracjami i stopniem równoległości 1 (lub 46 MiB przy 1 iteracji).

  • scrypt z N = 2^17, r = 8, p = 1, gdy Argon2 jest niedostępny.

  • bcrypt ze współczynnikiem pracy (work factor) 10 lub wyższym (pamiętaj o limicie 72 bajtów danych wejściowych; wstępne hashowanie dłuższych haseł wymaga ostrożności).

  • PBKDF2-HMAC-SHA256 z 600 000 iteracji tylko tam, gdzie wymaga tego zgodność z FIPS.

javascript
// Node.js with the argon2 package
import argon2 from "argon2";

const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 19456, // KiB = 19 MiB
  timeCost: 2,
  parallelism: 1,
});

// Later, on login:
const ok = await argon2.verify(hash, submittedPassword);

Uwaga

Dobierz koszt tak, aby jeden hash zajmował na serwerze logowania mniej więcej od 100 do 250 ms. Prawdziwy użytkownik tego nie zauważy, ale atakujący zostanie ograniczony do kilku tysięcy prób na sekundę na rdzeń zamiast miliardów. Przy każdym podniesieniu parametrów hashuj hasło ponownie po udanym logowaniu, aby stare hashe same się aktualizowały.

Zasady dotyczące haseł, które naprawdę pomagają (NIST SP 800-63B)

Reguły złożoności, które większość stron wciąż wymusza (jedna wielka litera, jeden symbol, zmiana co 90 dni), prowadzą do przewidywalnych haseł w stylu Summer2026! i skłaniają ludzi do ich ponownego używania. Aktualne wytyczne NIST SP 800-63B zastępują je regułami, które mierzą to, co naprawdę ważne:

  • Minimum 8 znaków, gdy wymagane jest również MFA, i co najmniej 15 znaków dla hasła używanego samodzielnie; dopuszczaj co najmniej 64 znaki.

  • Żadnych reguł złożoności i żadnej wymuszonej okresowej zmiany; wymagaj zmiany hasła tylko wtedy, gdy istnieją dowody jego przejęcia.

  • Sprawdzaj każde nowe hasło z listą haseł, które wyciekły (API zakresów Have I Been Pwned pozwala to zrobić bez wysyłania hasła) i odrzucaj te, które już wyciekły.

  • Pozwalaj na wklejanie i menedżery haseł, akceptuj spacje i znaki Unicode oraz pokazuj wskaźnik siły hasła oparty na entropii, a nie na regułach.

Nasz Test Siły Hasła pokazuje, czym te miary różnią się od starych reguł: szacuje czas złamania na podstawie entropii i wykrywania wzorców oraz sprawdza hasło z danymi z wycieków, co daje znacznie bardziej przydatną informację zwrotną niż czerwony komunikat „wymagany symbol”.

MFA i passkeys

Uwierzytelnianie wieloskładnikowe sprawia, że skradzione hasło prowadzi donikąd. Oferuj je wszystkim i wymagaj go od ról administracyjnych, finansowych i wsparcia. Uszereguj opcje według odporności na phishing: passkeys i klucze bezpieczeństwa FIDO2 nie dają się wyłudzić phishingiem, bo poświadczenie jest powiązane z Twoim prawdziwym originem; aplikacje uwierzytelniające (TOTP) są dobre; kody SMS są lepsze niż nic, ale można je przechwycić przez SIM swapping. Passkeys są obsługiwane we wszystkich aktualnych przeglądarkach i systemach operacyjnych i całkowicie eliminują hasło, a wraz z nim credential stuffing jako kategorię ataku.

Chroń ścieżkę odzyskiwania konta równie starannie jak logowanie: kody odzyskiwania przechowywane jako hashe, resety przez e-mail z jednorazowymi tokenami, które wygasają w ciągu 15 minut, i żadnych pytań pomocniczych.

Limitowanie żądań, blokady i ochrona przed botami

Stosuj rate limiting na endpointach logowania, rejestracji, resetu hasła i MFA — dla każdego adresu IP i dla każdego konta — i po przekroczeniu limitu zwracaj 429 Too Many Requests z nagłówkiem Retry-After (nasz przewodnik po błędzie HTTP 429 opisuje, jak powinni reagować klienci). Połącz to z rosnącym opóźnieniem lub tymczasową blokadą po powtarzających się nieudanych próbach na jednym koncie oraz z CAPTCHA lub wyzwaniem proof-of-work na endpointach narażonych na rozproszone ataki. Zapisuj w logach każde nieudane logowanie wraz ze źródłowym adresem IP, aby wzorzec ataku credential stuffing był widoczny w ciągu minut, a nie miesięcy.

nginx
# nginx: 5 login attempts per minute per client IP
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /api/login {
    limit_req zone=login burst=4 nodelay;
    limit_req_status 429;
    proxy_pass http://app;
}

Ostrzeżenie

Komunikaty o błędach dla „nieznanego użytkownika” i „błędnego hasła” muszą być identyczne, a czas odpowiedzi taki sam w obu przypadkach (hashuj fikcyjne hasło, gdy użytkownik nie istnieje). W przeciwnym razie formularz logowania staje się jednocześnie API do enumeracji użytkowników.

Sesje, ciasteczka i CSRF

Po zalogowaniu ciasteczko sesji jest użytkownikiem, więc zasługuje na taką samą ochronę jak hasło. Większość pracy wykonują trzy atrybuty ciasteczka i jeden prefiks nazwy:

  • Secure oznacza, że ciasteczko nigdy nie jest wysyłane przez zwykłe HTTP, więc nie da się go podsłuchać w publicznej sieci Wi-Fi.

  • HttpOnly sprawia, że ciasteczko jest niewidoczne dla JavaScriptu, więc błąd XSS nie pozwoli go odczytać.

  • SameSite=Lax (lub Strict dla paneli administracyjnych) sprawia, że ciasteczko nie jest dołączane do międzywitrynowych żądań POST, co neutralizuje większość ataków CSRF.

  • Prefiks __Host- sprawia, że przeglądarka akceptuje ciasteczko tylko wtedy, gdy ma ono atrybut Secure, Path=/ i nie ma atrybutu Domain, więc subdomena nie może go nadpisać.

http
Set-Cookie: __Host-session=9f1c7e2a...; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=28800

Wskazówka

Akcje zmieniające stan nigdy nie mogą być dostępne przez GET. Link w rodzaju /account/delete?id=42 może zostać wywołany przez tag <img> na dowolnej stronie odwiedzanej przez użytkownika, niezależnie od tego, jak dobre są flagi Twoich ciasteczek.

CSRF: druga linia obrony za SameSite

Cross-site request forgery (CSRF) nakłania zalogowaną przeglądarkę do wysłania z innej strony żądania, które zmienia stan w Twoim serwisie. Ciasteczka SameSite powstrzymują typowy przypadek, ale na każdym żądaniu innym niż GET utrzymuj drugą linię obrony: token anty-CSRF przypisany do sesji w ukrytym polu lub własnym nagłówku albo sprawdzenie, czy nagłówek Origin (lub Sec-Fetch-Site) odpowiada Twojemu originowi. Większość frameworków (Django, Rails, Laravel, server actions w Next.js) robi to domyślnie; błąd polega na wyłączeniu tej ochrony dla endpointu API, a potem wywoływaniu go z przeglądarki.

Identyfikatory sesji, rotacja i JWT

Generuj identyfikatory sesji z co najmniej 128 bitami losowości, zmieniaj identyfikator przy logowaniu i przy każdej zmianie uprawnień, aby udaremnić session fixation, wygaszaj sesje po okresie bezczynności i daj użytkownikom przycisk „wyloguj ze wszystkich urządzeń”, który unieważnia je po stronie serwera. Tokeny JWT niech będą krótkotrwałe (minuty, z refresh tokenem, który można odwołać); nigdy nie przechowuj ich w localStorage, gdzie może je odczytać dowolny skrypt, a wyciek klucza podpisującego traktuj jak pełne naruszenie bezpieczeństwa, bo każdy token, który ten klucz kiedykolwiek podpisał, można teraz podrobić.

Injection i XSS: waliduj dane wejściowe, koduj dane wyjściowe

Injection (A05:2025, wstrzykiwanie kodu) i cross-site scripting to ten sam błąd w różnych miejscach: dane od użytkownika trafiają do interpretera (SQL, powłoki, zapytania LDAP, strony HTML) tak, jakby były kodem. Rozwiązanie też jest wszędzie takie samo: oddzielaj dane od kodu i nigdy nie buduj polecenia przez sklejanie stringów.

Advertisement

Zapytania parametryzowane zamiast sklejania stringów

W przypadku SQL używaj prepared statements lub ORM, który je generuje; baza danych traktuje wtedy dane wejściowe jako wartość, która nigdy nie zmieni struktury zapytania. Ta sama zasada dotyczy poleceń powłoki (przekazuj tablicę argumentów, nigdy string), filtrów NoSQL (odrzucaj w danych od użytkownika obiekty operatorów, takie jak {"$gt": ""}) i ścieżek plików (rozwiąż ścieżkę i upewnij się, że pozostaje w docelowym katalogu).

javascript
// Vulnerable: the input becomes part of the query text
const rows = await db.query(`SELECT * FROM users WHERE email = '${email}'`);

// Safe: the driver sends the value separately from the query
const rows = await db.query("SELECT * FROM users WHERE email = $1", [email]);

// Python / psycopg: same idea
cur.execute("SELECT * FROM users WHERE email = %s", (email,))

Kodowanie danych wyjściowych powstrzymuje XSS

Do cross-site scriptingu dochodzi, gdy tekst kontrolowany przez użytkownika trafia na stronę bez zakodowania go odpowiednio do kontekstu, w którym się znajdzie. Nowoczesne silniki szablonów (React i JSX, Vue, Jinja2, Blade, ERB) domyślnie kodują dane; dziś XSS bierze się zwykle z furtek, które tę ochronę omijają: dangerouslySetInnerHTML, v-html, |safe, innerHTML oraz budowania adresów URL lub inline'owych handlerów zdarzeń z danych użytkownika. Koduj dane dokładnie pod dany kontekst, a rozbudowany HTML oczyszczaj specjalnie do tego stworzoną biblioteką, taką jak DOMPurify, a nie wyrażeniem regularnym.

Gdzie trafiają daneJak kodowaćPrzykład
Treść HTMLEncje HTML< zmienia się w &lt;, a " w &quot;
Atrybut HTMLEncje w atrybucie ujętym w cudzysłówZawsze ujmuj atrybut w cudzysłów; koduj " i '
JavaScriptNie wstrzykuj danych do treści skryptu; przekazuj je przez atrybuty data- lub blok JSON <script type="application/json"></script> wewnątrz stringa zamienia się w \u003c/script\u003e
Parametr URLKodowanie procentowe (percent-encoding)encodeURIComponent(value)
Wartość CSSUnikaj całkowicie; wybieraj nazwy klas z listy dozwolonychNigdy nie wstawiaj danych od użytkownika do style

SSRF, przesyłanie plików i deserializacja

Server-side request forgery (SSRF): jeśli Twój serwer pobiera adres URL podany przez użytkownika (webhooki, proxy obrazów, podglądy linków), atakujący może skierować go na usługi wewnętrzne lub endpoint metadanych chmury 169.254.169.254 i odczytać poświadczenia. Najpierw rozwiąż nazwę hosta, odrzucaj zakresy prywatne i link-local, wyłącz przekierowania i umieść mechanizmy pobierające w segmencie sieci, z którego nie da się dotrzeć do niczego wewnętrznego.

Przesyłanie plików: sprawdzaj typ pliku na podstawie jego zawartości, a nie rozszerzenia czy nagłówka Content-Type wysłanego przez klienta; egzekwuj limit rozmiaru; przechowuj pliki poza katalogiem głównym serwera WWW lub w object storage pod losową nazwą, którą sam generujesz; a jeśli to możliwe, serwuj je z osobnego originu z nosniff i Content-Disposition: attachment. Nigdy nie pozwól, aby przesłany plik trafił tam, gdzie serwer WWW go wykona.

Deserializacja i mass assignment: nigdy nie deserializuj niezaufanych danych w formacie, który może tworzyć instancje dowolnych klas (natywna serializacja Javy, pickle w Pythonie, unserialize w PHP, YAML z niestandardowymi tagami); używaj JSON ze schematem. Wiąż treść żądania z jawną listą dozwolonych pól, aby użytkownik nie mógł wysłać POST-em "role": "admin" do modelu, który akurat ma taką kolumnę.

Ostrzeżenie

Walidacja służy do sprawdzania kształtu danych (czy to e-mail, dodatnia liczba całkowita, jedna z tych pięciu wartości?), a nie do zapewniania bezpieczeństwa. Czarne listy, które usuwają <script> lub cudzysłowy, zawsze da się obejść. Akceptuj tylko to, czego oczekujesz, a potem koduj dane na wyjściu i parametryzuj przy zapisie.

Broken Access Control: ryzyko numer jeden

Broken Access Control (błędy kontroli dostępu) zajmuje pierwsze miejsce w OWASP Top 10 od 2021 roku i utrzymuje je jako A01:2025. To nie pojedynczy błąd, lecz nawyk: przy każdym żądaniu sprawdza się, kim ktoś jest (uwierzytelnianie), ale zapomina się sprawdzić, do czego ma dostęp (autoryzacja). Klasyczna postać to insecure direct object reference (IDOR): GET /api/invoices/1042 działa dla właściciela faktury, ale też dla każdego, kto zmieni numer.

  • Domyślnie odmawiaj. Każda trasa wymaga jawnej reguły przyznającej dostęp; brak reguły oznacza 403, a nie 200.

  • Egzekwuj na serwerze, dla każdego obiektu. Ukrycie przycisku w interfejsie to nie kontrola dostępu. Każdy odczyt i zapis musi potwierdzać, że bieżący użytkownik jest właścicielem konkretnego rekordu lub ma do niego uprawnienia — również w endpointach zbiorczych, eksportach i zadaniach w tle.

  • Używaj nieprzewidywalnych identyfikatorów tam, gdzie to pomaga (UUID), ale nigdy na nich nie polegaj: ukrycie to nie autoryzacja.

  • Zablokuj CORS. Access-Control-Allow-Origin: * z poświadczeniami albo odbijanie dowolnego nagłówka Origin wysłanego w żądaniu oddaje Twoje API każdej stronie, którą odwiedza użytkownik.

  • Wyłącz listowanie katalogów, blokuj .git, .env, kopie zapasowe i pliki konfiguracyjne na poziomie serwera WWW, a panele administracyjne trzymaj poza publicznym internetem albo za MFA i listą dozwolonych adresów IP.

  • Limituj i loguj błędy autoryzacji. Seria odpowiedzi 403 w jednej sesji oznacza trwający atak enumeracyjny.

javascript
// Express: ownership check on every object access
app.get("/api/invoices/:id", requireAuth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (!invoice || invoice.ownerId !== req.user.id) {
    return res.status(404).end(); // 404, not 403: don't confirm the record exists
  }
  res.json(invoice);
});

Uwaga

Testuj kontrolę dostępu tak, jak robi to atakujący: zaloguj się jako użytkownik o niskich uprawnieniach, przechwyć każde żądanie i odtwórz każde z nich z identyfikatorami innego użytkownika oraz bez nagłówka Authorization. Automatyczne skanery znajdują podatności typu injection, ale prawie nigdy nie znajdują błędów autoryzacji — dlatego te błędy przetrwają latami.

Warstwa 5: zależności i łańcuch dostaw oprogramowania

Typowa aplikacja webowa to może 5% kodu napisanego przez Ciebie i 95% kodu pobranego z zewnątrz. Dlatego Software Supply Chain Failures (błędy łańcucha dostaw oprogramowania) debiutuje na pozycji A03 w OWASP Top 10 z 2025 roku i dlatego w DBIR 2026 wykorzystanie podatności wyprzedziło skradzione dane logowania. We wrześniu 2025 roku wystarczył jeden opiekun pakietów, który dał się złapać na phishing, by do chalk, debug i 16 innych pakietów npm — pobieranych łącznie ponad dwa miliardy razy w tygodniu — trafiło złośliwe oprogramowanie kradnące kryptowaluty; każdy projekt, który w tym czasie zainstalował nieprzypiętą wersję, automatycznie je pobrał.

  • Commituj lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, poetry.lock, go.sum) i w CI instaluj zależności przez npm ci, aby buildy były powtarzalne, a nowe wydanie upstream nie mogło wślizgnąć się bez przeglądu.

  • Skanuj w sposób ciągły: npm audit, pip-audit, bundler-audit, GitHub Dependabot lub Renovate do aktualizacji oraz skaner kontenerów, taki jak Trivy lub Grype, dla warstwy systemu operacyjnego.

  • Opóźniaj aktualizacje niezwiązane z bezpieczeństwem o kilka dni (minimumReleaseAge w Renovate), aby zatrute wydanie zwykle zostało wycofane, zanim je wdrożysz — ale poprawki bezpieczeństwa stosuj natychmiast.

  • Przypinaj zewnętrzne akcje i skrypty w CI do SHA commita i używaj Subresource Integrity (integrity="sha384-...") dla każdego skryptu ładowanego z publicznego CDN.

  • Dawaj CI minimalne uprawnienia: tokeny tylko do odczytu tam, gdzie to możliwe, krótkotrwałe poświadczenia OIDC zamiast długowiecznych sekretów i prawa do publikacji ograniczone do zadania wydającego release.

  • Generuj SBOM (CycloneDX lub SPDX) podczas builda, aby po pojawieniu się kolejnego CVE klasy Log4Shell odpowiedzieć na pytanie „czy nas to dotyczy?” w kilka minut.

bash
# Reproducible install + audit in CI
npm ci --ignore-scripts
npm audit --audit-level=high

# Pin a GitHub Action to a commit, not a floating tag
# uses: actions/checkout@v4                 <- can change underneath you
# uses: actions/checkout@<full-commit-sha>  # v4.2.2

# Subresource Integrity for a CDN script (hash from: openssl dgst -sha384 -binary lib.min.js | openssl base64 -A)
<script src="https://cdn.example.com/lib.min.js"
        integrity="sha384-<base64-hash>"
        crossorigin="anonymous"></script>

Wskazówka

npm ci --ignore-scripts blokuje skrypty uruchamiane podczas instalacji, z których korzysta większość złośliwego oprogramowania w npm; następnie włącz skrypty ponownie tylko dla nielicznych pakietów, które naprawdę potrzebują kroku budowania.

Jeśli korzystasz z WordPressa lub innego CMS-a, te same zasady dotyczą wtyczek i motywów, od których zaczyna się większość włamań na CMS-y. Aktualizuj rdzeń i każdą wtyczkę, usuwaj te, których nie używasz, i sprawdź w Wykrywaniu CMS, czego skaner może się dowiedzieć o Twoich wersjach.

Warstwa 6: hardening serwera (porty, poprawki, sekrety, kopie zapasowe)

Warstwa aplikacji nie ma znaczenia, jeśli serwer pod nią przyjmuje logowanie hasłem przez SSH, udostępnia bazę danych na publicznym porcie albo nie był aktualizowany od chwili postawienia. Dobre praktyki serwerowe są nudne — i to właśnie tędy wchodzi ransomware.

Zamknij każdy port, którego nie potrzebujesz

Publiczny serwer WWW potrzebuje otwartych portów 80 i 443 oraz SSH dostępnego z Twojego zakresu adresów IP. Bazy danych (3306, 5432, 27017), Redis (6379), Elasticsearch (9200), panele administracyjne i endpointy metryk powinny nasłuchiwać tylko na localhost lub w sieci prywatnej. Po każdej zmianie sprawdzaj to z zewnątrz za pomocą Sprawdzania Portów, bo właśnie taki widok ma atakujący, a grupy zabezpieczeń w chmurze łatwo źle odczytać.

bash
# Ubuntu: default-deny firewall, allow only web + SSH from your office range
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw enable

# SSH: keys only, no root password login
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
sudo systemctl reload ssh

Łataj regularnie, trzymaj sekrety poza kodem

Włącz automatyczne aktualizacje bezpieczeństwa systemu operacyjnego, zapisz się na listy bezpieczeństwa swojego środowiska uruchomieniowego i frameworka, a krytyczne CVE w czymkolwiek dostępnym z internetu traktuj jako zadanie na ten sam dzień. Uruchamiaj usługi jako użytkownicy bez uprawnień, w kontenerach lub z sandboxingiem systemd, aby przejęty proces nie mógł odczytać całej maszyny.

Sekrety (hasła do baz danych, klucze API, klucze podpisujące) nigdy nie powinny trafiać do repozytorium, warstwy obrazu Dockera ani do JavaScriptu po stronie klienta. Wczytuj je ze zmiennych środowiskowych wstrzykiwanych podczas wdrożenia lub z menedżera sekretów, zmieniaj je, gdy odchodzi ktoś, kto miał do nich dostęp, i skanuj historię repozytorium narzędziem takim jak gitleaks — bo klucz raz zacommitowany jest skompromitowany na zawsze, nawet po usunięciu commita.

Ostrzeżenie

Wszystko z prefiksem NEXT_PUBLIC_, VITE_ lub REACT_APP_ trafia do paczki ładowanej w przeglądarce i z definicji jest publiczne. Klucze API usług zewnętrznych umieść zamiast tego za własną trasą po stronie serwera. Nasz przewodnik jak przetestować publiczny endpoint API pokazuje, jak sprawdzić, co faktycznie ujawnia Twój frontend.

Kopie zapasowe odporne na ransomware i CDN przed serwerem

Stosuj zasadę 3-2-1: trzy kopie, na dwóch różnych nośnikach, jedna poza siedzibą, i zadbaj, aby co najmniej jedna kopia była niezmienna (immutable) lub offline, tak by ransomware, które dotrze do serwera, nie zaszyfrowało również kopii zapasowych. Szyfruj kopie, uwzględniaj w nich bazę danych i katalog z przesłanymi plikami, a przede wszystkim regularnie testuj odtwarzanie. Kopia zapasowa, z której nikt nigdy niczego nie odtworzył, to nadzieja, a nie plan. To czas przywrócenia decyduje, czy incydent będzie zwykłą przerwą w działaniu, czy końcem firmy.

Umieść CDN lub WAF (Cloudflare, Fastly, AWS CloudFront z WAF albo odpowiednik u Twojego hostingodawcy) przed serwerem źródłowym. Pochłania on wolumetryczne ataki DDoS, stosuje zarządzane reguły dla typowych payloadów injection i złych botów, ukrywa adres IP serwera źródłowego i daje Ci miejsce do egzekwowania limitów żądań oraz reguł geograficznych bez ingerencji w aplikację. Następnie skonfiguruj firewall serwera źródłowego tak, aby bezpośrednio do portu 443 docierały tylko zakresy IP CDN; w przeciwnym razie atakujący po prostu go obejdą. Sprawdzanie hostingu pokazuje, czy prawdziwy serwer źródłowy strony jest odsłonięty mimo CDN.

Uwierzytelnianie poczty: SPF, DKIM i DMARC

Bezpieczeństwo strony obejmuje też pocztę, która dostarcza resety haseł, faktury i odpowiedzi działu wsparcia. Bez SPF, DKIM i DMARC każdy może wysyłać wiadomości jako billing@yourdomain.com, a od lutego 2024 roku Google i Yahoo wymagają wszystkich trzech od nadawców masowych. Cały zestaw to trzy rekordy DNS TXT:

dns
yourdomain.com.                    TXT  "v=spf1 include:_spf.google.com -all"
google._domainkey.yourdomain.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
_dmarc.yourdomain.com.             TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s"

Uwaga

DMARC p=reject to także narzędzie ochrony marki: tylko on powstrzymuje kampanię phishingową przed wpisaniem dokładnie Twojej domeny w polu nadawcy (From). Raporty zbiorcze (rua=) pokazują, kto próbuje.

Zacznij DMARC od p=none, aby zbierać raporty, a następnie przejdź na p=quarantine i p=reject, gdy każdy uprawniony nadawca (platforma marketingowa, helpdesk, CRM) przejdzie weryfikację zgodności (alignment). Dodaj rekordy MTA-STS i TLS-RPT, aby wymusić szyfrowane dostarczanie poczty do Twoich serwerów, i opublikuj null MX (MX 0 .) w domenach, które nigdy nie wysyłają poczty, aby w ogóle nie dało się ich podszyć. Zweryfikuj każdy rekord w Sprawdzaniu Rekordu SPF, Sprawdzaniu DKIM i Sprawdzaniu DMARC, a jeśli spadnie dostarczalność, sprawdź swoje adresy IP nadawcze na czarnych listach w Sprawdzaniu Czarnej Listy IP.

Loguj, monitoruj i planuj na wypadek włamania

Dwie z dziesięciu kategorii OWASP 2025 dotyczą tego, co dzieje się po błędzie: Security Logging and Alerting Failures (A09, błędy logowania zdarzeń i alertowania) oraz nowa kategoria Mishandling of Exceptional Conditions (A10, niewłaściwa obsługa sytuacji wyjątkowych). Typowe włamanie wciąż pozostaje niewykryte miesiącami, bo dowody nigdy nie zostały zapisane — albo zostały, ale nikt do nich nie zajrzał.

  • Loguj zdarzenia bezpieczeństwa z kontekstem: każde udane i nieudane logowanie, zmiany MFA, resety haseł, zmiany uprawnień, odmowy dostępu, błędy walidacji danych wejściowych i działania administratorów — każde ze znacznikiem czasu, identyfikatorem użytkownika, źródłowym adresem IP i user agentem.

  • Nigdy nie zapisuj sekretów w logach: haseł, tokenów sesji, pełnych numerów kart, kluczy API. Maskuj je w warstwie zapisu logów, a nie w każdym miejscu wywołania.

  • Wysyłaj logi poza serwer do centralnego magazynu (CloudWatch, Loki, Elastic, SIEM) z retencją co najmniej 90 dni, aby atakujący z uprawnieniami roota nie mógł zatrzeć śladów.

  • Ustawiaj alerty na wzorce, a nie pojedyncze zdarzenia: 50 nieudanych logowań w ciągu minuty, skok liczby odpowiedzi 403 w jednej sesji, nowe konto administratora utworzone poza godzinami pracy, certyfikat wystawiony dla Twojej domeny, którego nikt u Ciebie nie zamawiał.

  • Odmawiaj w razie awarii (fail closed): gdy kontrola zależna (usługa uwierzytelniania, rate limiter, WAF) zwraca błąd, odrzuć żądanie. Kategoria A10 istnieje, bo tak wiele systemów przyznaje dostęp, gdy kontrola, która powinna była go zablokować, rzuca wyjątek.

  • Monitoruj z zewnątrz: dostępność, wygasanie certyfikatów, zmiany DNS, wpisy na czarnych listach i regresje nagłówków. Sprawdzanie Kondycji Domeny łączy testy DNS, SSL, uwierzytelniania poczty i nagłówków w jeden wynik, który możesz sprawdzać ponownie po każdym wdrożeniu.

Napisz plan reagowania na incydenty, zanim będzie potrzebny

Zdecyduj z wyprzedzeniem, kto ma dyżur, jak zmienić każde poświadczenie, jak przełączyć stronę w tryb tylko do odczytu, gdzie są czyste kopie zapasowe oraz który organ nadzorczy lub których klientów trzeba powiadomić i w ciągu ilu godzin (72 zgodnie z RODO). Raz w roku przeprowadź ćwiczenie typu tabletop. Zespoły z przećwiczonym planem wracają do działania w ciągu dni; zespoły bez planu improwizują tygodniami.

Wskazówka

Dodaj plik security.txt pod adresem /.well-known/security.txt (RFC 9116) z adresem kontaktowym i kluczem PGP. Badacze, którzy znajdą błąd na Twojej stronie, skorzystają z niego; w przeciwnym razie mogą opisać błąd publicznie.

Testuj: skanery, testy penetracyjne i ciągła weryfikacja

Każde z powyższych zabezpieczeń da się zweryfikować, a weryfikację warto w miarę możliwości zautomatyzować, żeby z czasem nie zanikła. Rozsądna drabina — od darmowych i natychmiastowych testów po okresowe i płatne:

TestNarzędzieJak często
Konfiguracja TLS, łańcuch, wygaśnięcieSprawdzanie Certyfikatu SSL, SSL Labs, testssl.shPo każdej zmianie certyfikatu lub serwera; wygaśnięcie codziennie
Nagłówki bezpieczeństwa i CSPSprawdzanie Nagłówków HTTP, MDN HTTP ObservatoryPo każdym wdrożeniu (dodaj do CI)
Otwarte portySprawdzanie Portów, nmapPo każdej zmianie firewalla lub konfiguracji chmury
DNS, DNSSEC, uwierzytelnianie pocztySprawdzanie Kondycji Domeny, Sprawdzanie DMARCCo miesiąc i po każdej zmianie w DNS
Nieaktualne subdomenyWyszukiwarka SubdomenCo kwartał i przy każdym wyłączaniu usługi
Zależności ze znanymi podatnościaminpm audit, Dependabot, TrivyPrzy każdym buildzie
Błędy na poziomie kodu (SAST)Semgrep, CodeQLPrzy każdym pull requeście
Podatności działającej aplikacji (DAST)OWASP ZAP, NucleiCo tydzień na środowisku stagingowym
Autoryzacja i logika biznesowaRęczny test penetracyjny lub program bug bountyRaz w roku i po wdrożeniu ważnych nowych funkcji

Skanery dobrze radzą sobie z injection, nagłówkami i przestarzałymi komponentami, a słabo z autoryzacją i logiką biznesową, więc zaplanuj budżet na co najmniej jeden test wykonywany przez człowieka rocznie dla wszystkiego, co obsługuje płatności lub dane osobowe. Naprawiaj według ekspozycji: wszystko, co nieuwierzytelniony użytkownik może wykorzystać z internetu, ma pierwszeństwo.

Lista kontrolna bezpieczeństwa strony internetowej

Skopiuj ją do README projektu lub systemu zgłoszeń. Każdy wiersz to jedna z opisanych wyżej praktyk, sformułowana tak, aby dało się ją oznaczyć jako wykonaną lub nie; ostatnia kolumna to dowód.

WarstwaPraktykaGotowe, gdy
DomenaRegistrar lock i MFA na koncie u rejestratora; automatyczne odnawianie włączoneWHOIS pokazuje clientTransferProhibited; wygaśnięcie za ponad 12 miesięcy
DNSStrefa podpisana DNSSEC; rekord CAA wymieniający tylko Twoje CAdig +dnssec zwraca RRSIG; rekord DS obecny w strefie nadrzędnej
DNSBrak wiszących rekordów CNAME i AKażda nazwa hosta z Wyszukiwarki Subdomen wskazuje zasób pod Twoją kontrolą
TLSTylko TLS 1.2+, preferowany TLS 1.3, serwowany pełny łańcuchSprawdzanie Certyfikatu SSL: łańcuch kompletny, TLS 1.0/1.1 odrzucane
TLSHSTS z max-age na rok, includeSubDomains, na liście preloadDomena widnieje na hstspreload.org
TLSOdnawianie zautomatyzowane przez ACME; wygaśnięcie monitorowanecertbot renew --dry-run przechodzi; alert ustawiony na 14 dni przed wygaśnięciem
NagłówkiCSP (oparta na nonce), frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyOcena A w Sprawdzaniu Nagłówków HTTP
UwierzytelnianieHashowanie Argon2id lub bcrypt; zasady haseł NIST; sprawdzanie z listą wyciekówJeden hash trwa od 100 do 250 ms; brak reguł złożoności
UwierzytelnianieMFA dostępne dla wszystkich, wymagane dla administratorów; obsługa passkeysLogowanie administratora niemożliwe bez drugiego składnika
UwierzytelnianieLimity żądań na endpointach logowania, resetu hasła i MFA dla każdego IP i każdego kontaSzósta próba w ciągu minuty zwraca 429
SesjeCiasteczko __Host- z Secure, HttpOnly, SameSite; rotacja ID przy logowaniuAtrybuty ciasteczka widoczne w DevTools; stara sesja nieważna po zalogowaniu
Dane wejścioweZapytania parametryzowane wszędzie; kodowanie wyjścia zależne od kontekstu; przesyłane pliki walidowane po zawartościPrzeszukanie kodu nie znajduje zapytań sklejanych ze stringów; payloady XSS wyświetlają się jako tekst
Kontrola dostępuRouting z domyślną odmową; sprawdzanie własności każdego obiektu; restrykcyjny CORSOdtworzenie żądań z identyfikatorami innego użytkownika zwraca 404 lub 403
ZależnościLockfile w repozytorium; npm ci; audyt w CI; akcje przypięte do SHA; SRI dla skryptów z CDNBuild kończy się błędem przy CVE o wysokiej ważności
SerwerPublicznie tylko 80 i 443; SSH wyłącznie z kluczami; automatyczne aktualizacje bezpieczeństwa; sekrety w zmiennych środowiskowych lub menedżerze sekretówSprawdzanie Portów pokazuje, że 22, 3306 i 6379 są zamknięte od strony internetu
Kopie zapasowe3-2-1 z jedną kopią niezmienną; odtwarzanie przetestowaneOstatni udany test odtwarzania nie starszy niż 90 dni
PocztaSPF -all, DKIM, DMARC p=reject, MTA-STSSprawdzanie DMARC zaliczone; raporty zbiorcze napływają
MonitoringZdarzenia uwierzytelniania i autoryzacji logowane centralnie; alerty na wzorce; zewnętrzny monitoring dostępności, certyfikatów i DNSTestowy alert wysłany i odebrany
ReagowanieSpisany plan reagowania na incydenty; opublikowany security.txt; przeprowadzone ćwiczenie tabletopPlan przejrzany w ciągu ostatnich 12 miesięcy

Jak to się ma do OWASP Top 10:2025

OWASP Top 10 to najczęściej cytowana lista zagrożeń dla aplikacji webowych, a edycja z 2025 roku zmieniła kolejność i wprowadziła dwie nowe kategorie. Jeśli klient, audytor lub framework zgodności zapyta, jak się do niej odnosisz, oto zestawienie z praktykami z tego przewodnika:

OWASP Top 10:2025Praktyki z tego przewodnika
A01 Broken Access ControlDomyślna odmowa, kontrola dla każdego obiektu, restrykcyjny CORS, zabezpieczone panele administracyjne
A02 Security MisconfigurationNagłówki bezpieczeństwa, HSTS, zamknięte porty, usunięte nagłówki z wersjami, wyłączone listowanie katalogów
A03 Software Supply Chain Failures (nowa)Lockfile, audyty, przypięte akcje, SRI, SBOM, CI z minimalnymi uprawnieniami
A04 Cryptographic FailuresTLS 1.2+ i 1.3, HSTS, Argon2id, zarządzanie sekretami, szyfrowane kopie zapasowe
A05 InjectionZapytania parametryzowane, kodowanie danych wyjściowych, CSP, walidacja przesyłanych plików
A06 Insecure DesignModel zagrożeń dla każdej warstwy, domyślne zachowanie fail closed, limitowanie żądań uwzględnione w projekcie
A07 Authentication FailuresZasady haseł NIST, sprawdzanie wycieków, MFA i passkeys, rotacja sesji
A08 Software or Data Integrity FailuresSRI, podpisane i przypięte zależności, bezpieczna deserializacja
A09 Security Logging and Alerting FailuresCentralne logi, alerty na wzorce, monitoring zewnętrzny
A10 Mishandling of Exceptional Conditions (nowa)Fail closed, jednolite odpowiedzi błędów, żadnych stack trace'ów dla użytkowników

Uwaga

OWASP ASVS (Application Security Verification Standard) przekłada ten sam materiał na ponumerowaną listę kontrolną do audytów. Poziom 1 to realistyczny cel dla każdej publicznej strony; poziom 2 — dla wszystkiego, co przetwarza dane osobowe lub finansowe.

Sprawdź nagłówki bezpieczeństwa swojej strony w kilka sekund

Darmowe Sprawdzanie Nagłówków HTTP od DNS Robot pobiera dowolny adres URL i ocenia jego nagłówki bezpieczeństwa w skali od A do F: HSTS, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy i Permissions-Policy — z dokładną znalezioną wartością i informacją, czego brakuje. Bez rejestracji.

Wypróbuj Sprawdzanie Nagłówków HTTP

Advertisement

Bezpieczeństwo strony internetowej — najczęstsze pytania

Wymuś HTTPS z nowoczesnym TLS i HSTS, wysyłaj restrykcyjne nagłówki bezpieczeństwa (zwłaszcza Content Security Policy), hashuj hasła algorytmem Argon2id i chroń logowanie za pomocą MFA oraz limitów żądań, używaj zapytań parametryzowanych i kodowania danych wyjściowych, egzekwuj kontrolę dostępu na serwerze dla każdego obiektu, aktualizuj i przypinaj zależności, zamknij nieużywane porty i centralnie zbieraj logi zdarzeń bezpieczeństwa. Zacznij od zabezpieczenia domeny i DNS, bo wszystko inne zależy od tego, czy nadal kontrolujesz swoją domenę.

Powiązane narzędzia

HTTP Headers CheckSSL Certificate CheckPort CheckerDomain Health CheckerDMARC CheckerSubdomain FinderPassword Strength Tester

Powiązane artykuły

Czym jest łańcuch certyfikatów SSL? Jak działaX-Frame-Options Explained: Fix “Refused to Connect” in an iframeHTTP Error 429 Too Many Requests: Przyczyny i sposoby naprawyWhois domeny: jak sprawdzić właściciela i odczytać rekord

Spis treści

  • Czym właściwie jest bezpieczeństwo strony internetowej
  • Stos bezpieczeństwa strony: sześć warstw do ochrony
  • Warstwa 1: zabezpiecz domenę i DNS
  • Warstwa 2: HTTPS i TLS skonfigurowane porządnie
  • Warstwa 3: nagłówki bezpieczeństwa HTTP
  • Warstwa 4: uwierzytelnianie odporne na credential stuffing
  • Sesje, ciasteczka i CSRF
  • Injection i XSS: waliduj dane wejściowe, koduj dane wyjściowe
  • Broken Access Control: ryzyko numer jeden
  • Warstwa 5: zależności i łańcuch dostaw oprogramowania
  • Warstwa 6: hardening serwera (porty, poprawki, sekrety, kopie zapasowe)
  • Uwierzytelnianie poczty: SPF, DKIM i DMARC
  • Loguj, monitoruj i planuj na wypadek włamania
  • Testuj: skanery, testy penetracyjne i ciągła weryfikacja
  • Lista kontrolna bezpieczeństwa strony internetowej
  • Jak to się ma do OWASP Top 10:2025
  • Często zadawane pytania