LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Przegląd bloga /Data Privacy/Tutorials / Utwardzanie infrastruktury internetowej: Kontrola obcych skryptów za...
Ten artykuł w innych językach:

Utwardzanie infrastruktury internetowej: Kontrola obcych skryptów za pomocą Content Security Policy (CSP)

Utwardzanie infrastruktury internetowej: Kontrola obcych skryptów za pomocą Content Security Policy (CSP)

Management Summary

Content Security Policy, czyli CSP, to reguły witryny określające, jakie źródła i programy może ładować przeglądarka. Służą ograniczaniu niepożądanego kodu i części ataków polegających na wstawianiu szkodliwej treści. Ma to znaczenie zwłaszcza na stronach korzystających z usług wielu zewnętrznych dostawców. Potrzebne funkcje muszą nadal działać, przy ograniczeniu zbędnego dostępu. CSP stanowi dodatkową warstwę ochrony: dozwolony program także może nadużywać danych, więc sama zgoda na źródło nie gwarantuje zaufania.

Przejdź do interaktywnego przykładu ↓

Spis treści
  1. Zakres ochrony CSP
  2. 1. Inwentaryzacja rzeczywistych zależności
  3. 2. Początek od polityki bez blokowania
  4. 3. Jednoznaczna odpowiedzialność za nagłówki
  5. 4. Zezwalanie na skrypty przez nonce lub hash
  6. 5. Oddzielna kontrola raportów i działania
  7. Pytania i odpowiedzi
  8. Źródła

Zakres ochrony CSP

Content Security Policy (CSP) określa zasoby dozwolone do pobrania oraz skrypty dozwolone do wykonania dla dokumentu. Cross-site scripting polega na uruchomieniu wstrzykniętego kodu wewnątrz strony. CSP utrudnia niektóre ataki tego rodzaju. Dopuszczony JavaScript nadal ma jednak dostęp do dokumentu. Sama obecność CSP nie rozpoznaje przejętej biblioteki z dozwolonego źródła.

Escapowanie zamienia znaki specjalne tak, aby tekst nie został odczytany jako kod. Walidacja sprawdza, czy przesłane wartości spełniają oczekiwane reguły. CSP uzupełnia te działania i kontrolę używanych bibliotek zewnętrznych. Lista dozwolonych hostów wskazuje dopuszczone serwery źródłowe. Nie sprawdza, czy każdy pobrany plik jest niezmieniony i godny zaufania. Nie zapewnia też zgody. Złośliwy skrypt nadal może kopiować wpisane dane formularza lub wysyłać dane do dozwolonych celów. CSP strony nie stanowi też niezawodnej bariery dla uprzywilejowanych rozszerzeń: Chrome oddziela izolowane content scripts od głównego kontekstu, w którym obowiązuje polityka strony.

Nginx lub WordPress dostarcza politykę odpowiedzi. Report-Only obserwuje; aktywna CSP blokuje niedozwolone zasoby. Dozwolone skrypty nadal wymagają zaufania.
Nginx lub WordPress dostarcza politykę odpowiedzi. Report-Only obserwuje; aktywna CSP blokuje niedozwolone zasoby. Dozwolone skrypty nadal wymagają zaufania.

1. Inwentaryzacja rzeczywistych zależności

Spis obejmuje skrypty, style, obrazy, czcionki, ramki i połączenia po interakcji. Istotne są rodzaje stron, języki, logowanie, zgoda i formularze. Menedżer tagów może dołączać dodatkowe cele, więc sam host kontenera nie tworzy pełnej listy zależności. Matomo Cloud wymaga rzeczywistych adresów instancji zamiast ogólnego dopuszczenia matomo.cloud.

’self’ oznacza ten sam origin, obejmujący schemat, host i port, a nie wszystkie subdomeny ani ten sam fizyczny serwer. default-src zapewnia wartość zastępczą dla określonych dyrektyw pobierania, ale nie dla base-uri, form-action i frame-ancestors. connect-src kontroluje połączenia przeglądarki, takie jak fetch, XHR, sendBeacon i WebSocket. CSP przeglądarki nie kontroluje dalszych żądań kontenera server-side GTM do platform reklamowych.

2. Początek od polityki bez blokowania

Każda dyrektywa to reguła dla określonego zasobu lub działania. Na przykład script-src kontroluje skrypty, form-action cele wysyłania formularzy, a frame-ancestors witryny, które mogą osadzać tę stronę. Poniższa polityka inwentaryzacyjna jest punktem wyjścia dla Report-Only w środowisku testowym. Skrypty i style inline są zapisane bezpośrednio w HTML zamiast w osobnych plikach. Te elementy oraz zasoby dostawców zewnętrznych nie zostały jeszcze dopuszczone. Typowa instalacja WordPressa wygeneruje zatem naruszenia. Bez dostosowania nie jest to gotowa konfiguracja produkcyjna.

default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
frame-src 'none';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'self';

Nagłówek Content-Security-Policy-Report-Only zgłasza wykryte naruszenia, ale ta polityka nie blokuje zasobów. Jednoczesna polityka blokująca nadal działa. Dopiero po sprawdzeniu wymaganych zasobów i procesów uzgodniona polityka może zostać włączona jako Content-Security-Policy. 'unsafe-inline’ ponownie dopuszcza szeroki zakres skryptów inline i nie zastępuje celowego zezwalania na poszczególne skrypty.

3. Jednoznaczna odpowiedzialność za nagłówki

Nagłówek odpowiedzi HTTP przekazuje informacje lub instrukcje wraz z treścią strony. Nginx może dostarczać statyczną politykę w takim nagłówku. Poniższy fragment należy do odpowiedniego istniejącego kontekstu server lub location; TLS, proxy, PHP i pozostałe nagłówki pozostają częścią pełnej konfiguracji. Nagłówek trafia z odpowiedzią do przeglądarki i dopiero tam jest oceniany. Nie zatrzymuje to wykonania PHP ani nie wykrywa ataku przed uruchomieniem PHP.

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

Przed planowanym przeładowaniem nginx -t sprawdza pełną konfigurację. Błąd powinien zatrzymać przeładowanie. Fragment przeszedł kontrolę składni w osobnej konfiguracji minimalnej; nie stanowi to weryfikacji istniejącej konfiguracji produkcyjnej.

sudo nginx -t && sudo systemctl reload nginx

Przy domyślnym dziedziczeniu add_header kontekst podrzędny z własnymi dyrektywami add_header przestaje dziedziczyć dyrektywy nadrzędne. always zmienia objęte statusy odpowiedzi, a nie dziedziczenie. Wspólny plik include pomaga zachować spójność. Nginx 1.29.3 wprowadził też add_header_inherit merge; opcja wymaga obsługiwanej wersji i kontroli niezamierzonych podwójnych nagłówków.

Bez dostępu do konfiguracji Nginx mała wtyczka WordPress przygotowana dla witryny może dodawać Report-Only do zwykłych odpowiedzi frontendu. To alternatywna ścieżka dostarczania, nie automatyczny mechanizm zapasowy Nginx. Przykład nie jest związany z WordPress 7.0.2 i nie obejmuje automatycznie panelu, logowania, REST ani plików cache wydawanych bezpośrednio.

<?php
/** Plugin Name: Example CSP Report-Only */
add_action('send_headers', static function () {
    if (is_admin() || headers_sent()) {
        return;
    }
    $policy = "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self';";
    header('Content-Security-Policy-Report-Only: ' . $policy);
});

Hook send_headers pozwala dodawać nagłówki odpowiedzi. Wcześniejszy output oraz pamięć podręczna przed aplikacją wymagają uwzględnienia. Kilka blokujących nagłówków CSP obowiązuje równocześnie; zezwolenie w jednym nie uchyla ograniczenia drugiego. Rzeczywiste nagłówki wymagają sprawdzenia w CDN, reverse proxy, serwerze WWW i aplikacji.

4. Zezwalanie na skrypty przez nonce lub hash

Nonce to kryptograficznie losowa, nieprzewidywalna wartość dla każdej nowej odpowiedzi HTML. Nagłówek i jawnie zaufane elementy script otrzymują tę samą wartość. Nonce akcji WordPressa nie nadaje się do tego celu. Zbiorczy filtr HTML oznaczający każdy skrypt mógłby dopuścić również wstrzyknięty kod. Cache i generowanie HTML muszą być skoordynowane z nonce.

Poniższy samodzielny dokument PHP pokazuje tę zależność, ale nie jest pełną poprawką WordPressa. no-store zapobiega w przykładzie zamierzonemu ponownemu użyciu zapisanej odpowiedzi. Rzeczywista aplikacja wymaga celowego przekazania nonce do wszystkich potrzebnych zaufanych skryptów.

<?php
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: default-src 'none'; script-src 'nonce-$nonce'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'");
header('Cache-Control: no-store');
header('Content-Type: text/html; charset=utf-8');
?>
<!doctype html><html lang="en"><meta charset="utf-8">
<title>Nonce example</title><p id="result">Pending</p>
<script nonce="<?= htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8') ?>">
document.getElementById('result').textContent = 'Allowed script ran';
</script></html>

Hash to obliczony odcisk treści skryptu. Hashe pasują do dokładnie znanej treści skryptu; zmiana treści lub białych znaków może zmienić hash. Nonce elementu script nie dopuszcza atrybutów zdarzeń inline, takich jak onclick. 'strict-dynamic’ może przekazywać zaufanie dynamicznie dołączanym skryptom i ogranicza znaczenie list hostów w obsługujących przeglądarkach. Takie przekazanie zaufania wymaga jawnej oceny. Dokumentacja GTM opisuje osadzenie obsługujące nonce oraz dodatkowe dyrektywy dla konkretnych funkcji tagów.

5. Oddzielna kontrola raportów i działania

Konsola przeglądarki to widok komunikatów w narzędziach deweloperskich. Bez adresu raportowania stanowi lokalne źródło diagnostyczne. Reporting-Endpoints i report-to mogą wskazać wcześniej skonfigurowany odbiornik HTTPS, a report-uri stanowi starszą ścieżkę zgodności. Nowoczesne raportowanie i report-uri używają różnych formatów JSON. Dostarczenie nie jest gwarantowane: obsługa przeglądarki, blokery i błędy sieci ograniczają kompletność. Adresy URL oraz ewentualne fragmenty skryptów w raportach wymagają ostrożnego przetwarzania i ograniczonej retencji.

Reporting-Endpoints: csp="https://reports.example.com/csp"
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp; report-uri https://reports.example.com/csp-legacy

Adresy są przykładami wymagającymi rzeczywistych odbiorników. Zgłoszone źródło nie powinno automatycznie trafiać na listę dozwolonych. Odbiór obejmuje nagłówki dokumentów, przekierowania, strony błędów, cache, formularze, multimedia, zmiany zgody i żądania śledzące. Sam HTTP 200 nie dowodzi poprawnego zebrania zdarzenia ani przetworzenia w systemie docelowym.

Pytania i odpowiedzi

Czy connect-src zatrzymuje każdy wyciek?

Nie. Dyrektywa kontroluje określone rodzaje połączeń, a nie wszystkie drogi wyjściowe lub dozwolone cele. Inne dyrektywy dotyczą na przykład obrazów i formularzy. Już dopuszczony kod, przejęte własne punkty końcowe i błędy logiki aplikacji pozostają osobnymi zagrożeniami.

Czy Report-Only działa przez element meta?

Nie. Report-Only wymaga nagłówka odpowiedzi HTTP. Nawet blokująca CSP w meta nie obsługuje wszystkich funkcji nagłówka, między innymi frame-ancestors. Podstawą spójnego wdrożenia jest rzeczywisty nagłówek odpowiedzi dokumentu.

Źródła

OWASP Top 10 · WordPress: functions.php i mechanizmy rozszerzeń

Zrozum przez eksperyment

Które skrypty dopuści ta CSP?

Zbuduj prostą regułę script-src. Przykładowa strona pokazuje, co byłoby dozwolone dla czterech fikcyjnych skryptów.

Menu · /app.js
Wykres · skrypt CDN
Wartości początkowe · inline z nonce
Nieoczekiwany skrypt inline bez nonce

Model jednej dyrektywy script-src. Nie pobiera ani nie uruchamia fikcyjnych skryptów. Bez strict-dynamic, hashy, fallbacków i wielu polityk. Prawdziwy nonce musi być nieprzewidywalny i nowy dla każdej odpowiedzi; demo to tylko przykład. Dozwolone skrypty zewnętrzne nadal wymagają zaufania.

Ten moduł działa w przeglądarce i nie wysyła ani nie zapisuje wpisanych danych.

Przejdź do odpowiedniego narzędzia →

Źródło ↗

Zrozum przez eksperyment

Jedna minuta: znajdziesz błąd?

script-src 'self' 'nonce-demo' 'unsafe-inline': czy skrypt inline bez pasującego nonce może działać w tym modelu?

Przejdź do odpowiedniego narzędzia →

Źródło ↗

Pojęcia do wypróbowania

Odkrywaj

Pojęcia do wypróbowania

Krótkie wyjaśnienie i mały eksperyment pomagają zrozumieć pojęcie.

Nonce

W CSP losowa wartość odnawiana dla każdej odpowiedzi może dopuścić konkretny skrypt. Nonce skryptu musi pasować do wartości w nagłówku.

Przeczytaj powiązany artykuł →

Krótkie wyjaśnienie

Przeczytaj powiązany artykuł →

Ćwiczenia obliczają wyniki w przeglądarce. Moduł nauki nie wysyła Twoich odpowiedzi.

Odkryj więcej eksperymentów →

Lukas Wójcik

Lukas Wójcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Kontakt

Masz pytanie lub pomysł na projekt internetowy? Napisz krótko, o co chodzi. Formularz korzysta z reCAPTCHA do ochrony przed spamem.

Napisanie komentarza

Obserwacje z innych wdrożeń, zastrzeżenia i pytania są tu mile widziane.

Adres e-mail nie jest publikowany. Pola obowiązkowe oznaczono gwiazdką.