Brak Content-Security-Policy

Co to jest

Twoja witryna nie wysyła nagłówka Content-Security-Policy. Ten nagłówek mówi przeglądarce, z jakich źródeł wolno jej ładować skrypty, obrazy, fonty i ramki iframe.

Bez niego przeglądarka uruchomi dowolny kod, który pojawi się w HTML — bez względu na to, czy umieścił go tam Twój zespół, czy atakujący przez XSS.

Dlaczego to problem

CSP to jedyna skuteczna obrona przed cross-site scripting (XSS). Gdy atakujący znajdzie gdzieś w aplikacji lukę, przez którą wepchnie <script>, bez CSP przeglądarka z radością ten skrypt uruchomi. Z CSP przeglądarka powie „tego źródła nie ma na liście dozwolonych” i skrypt nie zadziała.

Druga płaszczyzna — ochrona przed wstrzykniętymi drainerami i spamem SEO. Jeśli masz poprawnie skonfigurowany script-src, atakujący przez zhakowaną wtyczkę nie może łatwo dodać zewnętrznego skryptu.

Jak to naprawić

CSP to polityka, która może popsuć stronę. Wdróż ją najpierw w trybie report-only.

Faza 1 — report-only

Content-Security-Policy-Report-Only: default-src 'self'; img-src 'self' data: https:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; report-uri /csp-report

Ta polityka niczego nie blokuje — przy każdym naruszeniu wysyła tylko JSON na /csp-report. Przez kilka dni obserwuj logi, aby wiedzieć, jakich skryptów/obrazów/fontów strona rzeczywiście używa.

Faza 2 — dostroić listę dozwolonych

Na podstawie raportów zbuduj konkretną listę dozwolonych. Przykład dla WordPressa z Google Fonts i analityką Umami:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://i.xhs.cz;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  font-src 'self' https://fonts.gstatic.com;
  img-src 'self' data: https://*.gravatar.com;
  connect-src 'self' https://i.xhs.cz;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';

Faza 3 — przełączyć na enforce

Gdy tryb report-only nie zgłasza już żadnego prawidłowego naruszenia, zmień nagłówek z Content-Security-Policy-Report-Only na Content-Security-Policy.

Uwaga na 'unsafe-inline'

Skrypty inline (<script>...</script>) oraz obsługa zdarzeń inline (onclick="...") wymagają 'unsafe-inline'. Wtedy jednak CSP traci większość swojej wartości przeciw XSS. Lepiej użyć nonce lub hash i stopniowo usuwać skrypty inline. WordPress ma dla nonce wbudowane wsparcie.

Konkretna implementacja

Materiały źródłowe