Content Security Policy (CSP) to mechanizm przeglądarkowy, który pozwala twórcom aplikacji definiować, jakie zasoby mogą być ładowane i wykonywane w kontekście strony. Dzięki CSP można znacząco ograniczyć ryzyko ataków typu cross‑site scripting (XSS) oraz innych niepożądanych zachowań, takich jak wstrzyknięcie nieautoryzowanego kodu JavaScript. W środowiskach opartych na Next.js i React, gdzie komponenty są dynamicznie renderowane, wdrożenie CSP wymaga przemyślanej konfiguracji, aby nie zakłócić funkcjonalności aplikacji.
Model zagrożenia – dlaczego CSP jest potrzebny w aplikacjach React/Next.js
Współczesne aplikacje front‑endowe często ładują skrypty z wielu źródeł: CDN, własny serwer, a także dynamicznie generowane inline‑skrypty (np. wbudowane w szablony HTML). Atakujący mogą wykorzystać luki w sanitizacji danych wejściowych, aby wstrzyknąć własny kod JavaScript, co prowadzi do kradzieży tokenów, sesji lub wykonania nieautoryzowanych operacji. CSP działa jako warstwa obronna, blokując nieautoryzowane źródła i wymuszając stosowanie bezpiecznych metod ładowania zasobów.
Jak CSP działa – podstawowe dyrektywy i ich znaczenie
Polityka CSP jest definiowana w nagłówku HTTP Content‑Security‑Policy lub w tagu <meta>. Najważniejsze dyrektywy to:
default-src– domyślne źródło dla wszystkich typów zasobów, jeśli nie określono innej dyrektywy.script-src– kontroluje, skąd mogą pochodzić skrypty JavaScript.style-src– określa dozwolone źródła arkuszy CSS.img-src– reguluje pochodzenie obrazów.connect-src– definiuje, z jakich adresów aplikacja może nawiązywać połączenia (np. API, WebSocket).
W praktyce najważniejsze jest script-src, ponieważ to ona bezpośrednio chroni przed XSS. Zaleca się używanie hash‑ów ('sha256-…') lub nonce ('nonce‑…') dla inline‑skryptów, zamiast polegać na 'unsafe-inline', które wyłącza ochronę.
Przykładowa polityka CSP dla Next.js
Poniżej znajduje się minimalna, ale skuteczna polityka CSP, którą można dodać w pliku next.config.js przy użyciu middleware lub w funkcji getServerSideProps:
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'sha256-abc123' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' https://api.example.com; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'"
}
]
}
];
}
};
Ta polityka zezwala jedynie na skrypty pochodzące z własnego hosta oraz jednego zaufanego CDN, a inline‑skrypty muszą być zabezpieczone hash’em. Dla stylów dopuszczono 'unsafe-inline' jedynie w wyjątkowych przypadkach, co jest kompromisem przy użyciu bibliotek CSS‑in‑JS.
Fragmenty kodu: podatny vs. poprawiony
Rozważmy prosty komponent React, który wstawia treść pobraną z API bez sanitizacji:
function UnsafeComponent({html}) {
return ;
}
Takie podejście jest podatne na XSS, ponieważ dowolny kod HTML może zostać wykonany. Poprawiona wersja wykorzystuje bibliotekę sanitizującą i jednocześnie ogranicza CSP do zaufanych źródeł:
import DOMPurify from 'dompurify';
function SafeComponent({html}) {
const cleanHtml = DOMPurify.sanitize(html);
return ;
}
Połączenie sanitizacji po stronie aplikacji z restrykcyjną polityką CSP znacząco podnosi poziom bezpieczeństwa.
„CSP nie jest magiczną tarczą – jest elementem warstwy obrony, który musi współgrać z bezpiecznym kodem.”
Checklista wdrożenia CSP w Next.js i React
- Zidentyfikuj wszystkie źródła skryptów, stylów, obrazów i połączeń używanych w projekcie.
- Ustal, które inline‑skrypty są niezbędne; zastąp je hash‑ami lub nonce‑ami.
- Skonfiguruj nagłówek CSP w
next.config.jslub w serwerze pośredniczącym (NGINX, Vercel). - Włącz raportowanie CSP (dyrektywa
report-urilubreport-to) i monitoruj logi. - Testuj politykę w trybie raportowania (
Content-Security-Policy-Report-Only) przed włączeniem w trybie blokującym. - Użyj narzędzi deweloperskich przeglądarki do analizy naruszeń CSP i dopasuj politykę.
Typowe błędy i kompromisy przy implementacji CSP
Najczęstsze pułapki to:
- Używanie
'unsafe-inline'lub'unsafe-eval'– całkowicie wyłącza ochronę przed XSS. - Nieaktualne hash‑y – po zmianie kodu hash musi być zaktualizowany, w przeciwnym razie polityka blokuje legalny kod.
- Zbyt restrykcyjne
default-srcbez odpowiedniego dopasowania pod‑dyrektyw – może spowodować, że aplikacja przestanie ładować niezbędne zasoby, np. czcionki lub obrazy. - Brak raportowania – bez włączonego raportowania trudno wykryć, które zasoby są blokowane i dlaczego.
Rozwiązaniem jest iteracyjne podejście: najpierw uruchom politykę w trybie Report‑Only, zbierz dane, a następnie przełącz na tryb blokujący po wyeliminowaniu wszystkich fałszywych alarmów.
Debugowanie naruszeń CSP w przeglądarce i raportowanie
W konsoli deweloperskiej Chrome i Firefox pojawiają się komunikaty typu Refused to load the script … because it violates the following Content Security Policy directive: "script-src …". Kliknięcie w komunikat otwiera podgląd, które źródło zostało zablokowane. Dodatkowo, jeśli skonfigurowano report-uri, serwer otrzyma JSON z informacjami o naruszeniu, co umożliwia automatyczną analizę i aktualizację polityki.
Utrzymanie i aktualizacja polityki CSP
Polityka CSP nie jest jednorazowym ustawieniem – wymaga regularnego przeglądu. Każda nowa biblioteka, CDN lub funkcja (np. WebSocket) może wymagać dodania odpowiednich źródeł do dyrektyw. Dobrą praktyką jest integracja testów e2e, które weryfikują, czy aplikacja działa przy włączonym CSP, oraz monitorowanie raportów w systemie SIEM lub dedykowanym endpointzie.
Podsumowując, wdrożenie Content Security Policy w projektach Next.js i React to proces, który łączy dokładną inwentaryzację zasobów, właściwą konfigurację nagłówków oraz ciągłe monitorowanie. Dzięki temu zespół inżynierski może znacząco zredukować ryzyko XSS, zachowując pełną funkcjonalność aplikacji. Jeśli potrzebujesz pomocy przy audycie bezpieczeństwa, konfiguracji CSP lub integracji raportowania, skontaktuj się z nami w Coderia.it – razem zbudujemy solidną tarczę ochronną dla Twojego kodu.



