Content Security Policy (CSP) to mechanizm bezpieczeństwa przeglądarki, który mówi jej, z jakich miejsc wolno na danej stronie ładować i uruchamiać zasoby — skrypty, style, obrazy, czcionki, ramki czy połączenia sieciowe. Politykę przekazuje się nagłówkiem HTTP Content-Security-Policy (albo znacznikiem <meta>). Składa się ona z dyrektyw oddzielonych średnikami; każda dyrektywa ma nazwę i listę dozwolonych źródeł. CSP to przede wszystkim warstwa obrony przed atakami typu cross-site scripting (XSS, czyli wstrzykiwanie obcego kodu na stronę) oraz — dzięki dyrektywie frame-ancestors — przed clickjackingiem.
Jak działa Content Security Policy?
Serwer dokłada nagłówek Content-Security-Policy do odpowiedzi HTTP. Przeglądarka czyta tę politykę i przy każdej próbie pobrania zasobu lub uruchomienia kodu sprawdza, czy źródło jest na liście dozwolonych. Jeśli nie — blokuje zasób i (opcjonalnie) wysyła raport o naruszeniu. Włączona polityka domyślnie blokuje też skrypty osadzone bezpośrednio w stronie (<script>...</script>, atrybuty onclick, adresy javascript:) oraz dynamiczne uruchamianie kodu (eval(), Function(), setTimeout/setInterval z tekstem zamiast funkcji), o ile czegoś z tego jawnie nie dopuścimy.
Politykę egzekwuje przeglądarka po stronie użytkownika, ale to serwer decyduje o jej treści. Ważne, by nagłówek szedł przy każdej odpowiedzi HTML, a nie tylko na stronie głównej.
Jak dostarcza się politykę CSP?
- Nagłówek
Content-Security-Policy— metoda zalecana, obsługuje wszystkie funkcje (m.in.frame-ancestorsi raportowanie). - Nagłówek
Content-Security-Policy-Report-Only— polityka nie blokuje niczego, ale zgłasza naruszenia. Służy do testów przed wdrożeniem. - Znacznik
<meta http-equiv="Content-Security-Policy">— działa tylko część funkcji (nie ma m.in.frame-ancestorsani raportowania); bywa przydatny w aplikacjach renderowanych po stronie przeglądarki.
Lepiej omijać przestarzałe nagłówki X-Content-Security-Policy i X-Webkit-CSP.
Jakie są najważniejsze dyrektywy CSP?
Dyrektywy dzielą się na kilka grup. Najczęściej spotykane to dyrektywy pobierania (fetch directives), które ograniczają źródła konkretnych typów zasobów:
default-src— domyślna polityka, wartość zapasowa dla pozostałych dyrektyw pobierania.script-src— dozwolone źródła JavaScriptu (najważniejsza w obronie przed XSS).style-src— źródła arkuszy stylów.img-src,font-src,media-src— obrazy, czcionki, audio/wideo.connect-src— połączenia:fetch(),XMLHttpRequest, WebSocket, EventSource.object-src— wtyczki (<object>,<embed>); zalecana wartość to'none'.frame-src,worker-src,manifest-src— ramki, workery, manifest aplikacji.
Pozostałe grupy to dyrektywy dokumentu (base-uri, sandbox), dyrektywy nawigacji (form-action, frame-ancestors), dyrektywy raportowania (report-to, report-uri) oraz dyrektywa wymuszająca bezpieczny transport (upgrade-insecure-requests).
Jakie są słowa kluczowe listy źródeł?
'self'— zasoby z tej samej domeny (origin).'none'— całkowity zakaz ładowania danego typu zasobu.https:,data:— dozwolony schemat (np. wszystko po HTTPS albo data URI).- nazwa hosta lub wildcard, np.
*.example.com. 'unsafe-inline'— dopuszcza skrypty i style osadzone w stronie (osłabia ochronę, niezalecane).'unsafe-eval'— dopuszczaeval()i pokrewne (niezalecane).'nonce-...'— jednorazowy, losowy token przepuszczający konkretny skrypt osadzony w stronie.'sha256-...'/'sha384-...'/'sha512-...'— hasz przepuszczający skrypt lub styl o dokładnie tej zawartości.'strict-dynamic'— zaufanie nadane skryptowi przez nonce lub hasz przenosi na skrypty, które ten skrypt sam załaduje; ignoruje listy hostów oraz'unsafe-inline'.
Czym jest strict CSP oparte na nonce i haszach?
Listy dozwolonych hostów trudno utrzymać i często da się je obejść (np. przez otwarte przekierowania albo hostowane biblioteki podatne na JSONP). Współczesna, zalecana praktyka to strict CSP oparte na nonce lub haszach:
- Nonce — serwer przy każdej odpowiedzi generuje losowy token, wstawia go do nagłówka (
script-src 'nonce-RANDOM') oraz do atrybutunoncezaufanych tagów<script>. Token musi być inny przy każdej odpowiedzi i nie do przewidzenia. Wymaga dynamicznego renderowania szablonu. - Hasz — w polityce umieszcza się zakodowany Base64 skrót SHA-256/384/512 treści skryptu. Przeglądarka liczy skrót zawartości i ładuje zasób tylko przy zgodności. Dobre dla treści statycznej; każda zmiana, nawet spacji, unieważnia hasz.
'strict-dynamic'— pozwala skryptowi dopuszczonemu przez nonce lub hasz ładować kolejne skrypty bez oznaczania każdego z osobna; ułatwia podpięcie bibliotek zewnętrznych.
Typowa restrykcyjna polityka łączy te elementy z ograniczeniami: script-src 'nonce-RANDOM' 'strict-dynamic'; object-src 'none'; base-uri 'none'.
Jak CSP chroni przed XSS i clickjackingiem?
Przy XSS CSP działa jak druga warstwa obrony: nawet jeśli atakujący zdoła wstrzyknąć kod, restrykcyjna polityka nie pozwoli go uruchomić, bo wstrzyknięty skrypt nie zna ważnego nonce ani nie pasuje do żadnego hasza. To jednak nie zastępuje sprawdzania danych wejściowych i bezpiecznego kodowania danych na wyjściu po stronie serwera — CSP to obrona w głąb (defense in depth), a nie jedyne zabezpieczenie.
Przy clickjackingu dyrektywa frame-ancestors decyduje, kto może osadzić stronę w ramce ('none', 'self' albo konkretne domeny). Zastępuje ona starszy nagłówek X-Frame-Options. Dyrektywa base-uri 'none' blokuje podmianę znacznika <base>, a upgrade-insecure-requests wymusza HTTPS dla zasobów (to uzupełnienie, a nie zamiennik nagłówka HSTS).
Jak działa raportowanie naruszeń CSP?
CSP może zgłaszać każde naruszenie, więc bywa źródłem telemetrii bezpieczeństwa przydatnej zespołom SOC i przy monitoringu aplikacji.
- Reporting API (aktualne) — adresy zgłoszeń podaje nagłówek
Reporting-Endpoints, a polityka wskazuje grupę przezreport-to nazwa-grupy. Raport to JSON z polemtype: "csp-violation"i szczegółami (blockedURL,effectiveDirective,documentURL,dispositionitd.). report-uri(przestarzałe) — wysyła raport metodą POST na podany URL (Content-Type: application/csp-report). Dla zgodności ze starszymi przeglądarkami warto podać obie dyrektywy: nowsze użyjąreport-to, starszereport-uri.
Z perspektywy wykrywania zagrożeń strumień raportów CSP pozwala wcześnie zauważyć próby wstrzyknięcia skryptów, ładowanie zasobów z nieautoryzowanych domen (np. wyciek danych przez wstrzyknięty cel w connect-src) czy błędy konfiguracji. Tryb Content-Security-Policy-Report-Only pozwala obserwować takie zdarzenia bez blokowania ruchu — przydaje się przy strojeniu polityki i ocenie wpływu nowej wersji.
Jak wdrożyć CSP bez psucia aplikacji?
- Uruchom politykę w trybie
Content-Security-Policy-Report-Onlyi zbieraj raporty naruszeń. - Posprzątaj kod osadzony w stronie: przenieś skrypty do osobnych plików, zamień atrybuty zdarzeń (
onclick) naaddEventListener. - Dodaj nonce lub hasze do zaufanych skryptów; dla bibliotek zewnętrznych rozważ
'strict-dynamic'. - Domknij politykę ograniczeniami:
object-src 'none',base-uri 'none',frame-ancestors. - Przełącz na egzekwowany
Content-Security-Policy, dalej obserwując raporty.
Dowiedz się więcej
- Cloud Access Security Broker (CASB) — CASB wspiera egzekwowanie polityk bezpieczeństwa w ruchu do usług chmurowych, podobnie jak CSP.
- Cloud Security Posture Management (CSPM) — CSPM kontroluje konfigurację chmury, a CSP ogranicza zagrożenia po stronie treści i zasobów przeglądarki.
- SaaS Security Posture Management (SSPM) — SSPM ocenia bezpieczeństwo aplikacji SaaS, które CSP może dodatkowo chronić przez restrykcje ładowanych zasobów.