Zapewnienie ochrony CSP przed atakami typu XSS

Dzięki standardowi Content Security Policy (CSP) właściciel witryny może zagwarantować, że wszystkie treści wczytywane na stronie są godne zaufania. Dostawcy CSP ograniczają ataki typu cross-site scripting (XSS), ponieważ mogą blokować niebezpieczne skrypty wstrzyknięte przez atakujących. Jeśli jednak CSP nie jest wystarczająco rygorystyczny, można go łatwo pominąć. Więcej informacji znajdziesz w artykule na temat łagodzenia skryptów między witrynami (XSS) przy użyciu rygorystycznej zasady Content Security Policy (CSP). Lighthouse gromadzi dostawców CSP egzekwowanych w głównym dokumencie i zgłasza problemy z weryfikatora CSP, jeśli można je obejść.

Raport z narzędzia Lighthouse ostrzegający, że w trybie egzekwowania nie znaleziono CSP.
Raport Lighthouse z ostrzeżeniem, że w trybie egzekwowania nie znaleziono dostawcy CSP.

Wymagane praktyki dotyczące CSP, których nie da się pominąć

Zaimplementuj poniższe metody, aby uniknąć pominięcia CSP. Jeśli można ominąć CSP, Lighthouse wyśle ostrzeżenie o dużej wadze.

CSP jest kierowany na XSS

Aby kierować reklamy na XSS, CSP powinien zawierać dyrektywy script-src, object-src i base-uri. CSP nie może też zawierać błędów składni.

Zabezpieczenia script-src i object-src zabezpieczają stronę odpowiednio przed niebezpiecznymi skryptami i niebezpiecznymi wtyczkami. default-src może też służyć do konfigurowania ogólnych zasad zamiast wielu dyrektyw, w tym script-src i object-src.

base-uri zapobiega wstrzykiwaniu nieautoryzowanych tagów <base>, które mogą służyć do przekierowania wszystkich względnych adresów URL (np. skryptów) do domeny, którą kontrolują.

CSP używa liczb jednorazowych lub haszy, aby uniknąć pomijania list dozwolonych

Dostawca CSP konfigurujący listę dozwolonych dla systemu script-src opiera się na założeniu, że wszystkie odpowiedzi pochodzące z zaufanej domeny są bezpieczne i mogą być wykonywane jako skrypty. To założenie nie dotyczy jednak nowoczesnych aplikacji. Niektóre typowe, łagodne wzorce, takie jak ujawnianie interfejsów JSONP i hostowanie kopii biblioteki AngularJS, pozwalają hakerom uciec z kryteriów CSP.

W praktyce, chociaż dla autorów aplikacji może to nie być oczywiste, większość list dozwolonych (script-src) może zostać obejrzana przez osobę przeprowadzającą atak z wykorzystaniem błędu XSS. Zapewnia to niewielką ochronę przed wstrzykiwaniem skryptów. W przeciwieństwie do sytuacji metody oparte na kluczach bez użycia danych i szyfrach nie powodują tych problemów i ułatwiają wdrożenie i utrzymanie bezpieczniejszej zasady.

Na przykład ten kod używa punktu końcowego JSONP hostowanego w zaufanej domenie do wstrzyknięcia skryptu kontrolowanego przez atakującego:

CSP:

script-src https://trusted.example.com

HTML:

<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>

Aby uniknąć pominięcia, dostawca CSP powinien zezwalać na używanie poszczególnych skryptów z liczbami jednorazowymi lub haszami i używać listy „strict-dynamic” zamiast z listy dozwolonych.

Dodatkowe zalecenia dotyczące bezpiecznego CSP

Aby zwiększyć bezpieczeństwo i zgodność, zaimplementuj poniższe metody. Jeśli CSP nie będzie zgodna z jednym z rekomendacji, Lighthouse wyświetli ostrzeżenie o średnim wadze.

Skonfiguruj raportowanie CSP

Skonfiguruj miejsce docelowe raportowania, aby monitorować awarie. Miejsce docelowe raportowania możesz ustawić, używając dyrektyw report-uri lub report-to. Język report-to nie jest obecnie obsługiwany przez wszystkie nowoczesne przeglądarki, dlatego zaleca się użycie obu lub tylko report-uri.

Jeśli jakakolwiek treść narusza CSP, przeglądarka wyśle raport do skonfigurowanego miejsca docelowego. Sprawdź, czy w tym miejscu docelowym masz skonfigurowaną aplikację, która obsługuje te raporty.

Definiowanie CSP w nagłówku HTTP

CSP można zdefiniować w metatagu w ten sposób:

<meta http-equiv="Content-Security-Policy" content="script-src 'none'">

Jeśli to możliwe, zdefiniuj CSP w nagłówku odpowiedzi HTTP. Wstrzyknięcie przed metatagiem pomija CSP. Dodatkowo atrybuty frame-ancestors, sandbox i raportowanie nie są obsługiwane w przypadku dostawców CSP z metatagami.

Sprawdź, czy CSP jest zgodny wstecznie

Nie wszystkie przeglądarki obsługują liczby jednorazowe i hasze CSP, dlatego zalecamy dodanie atrybutu unsafe-inline w zastępstwie niezgodnych przeglądarek. Jeśli przeglądarka nie obsługuje liczb jednorazowych/haszów, parametr unsafe-inline jest ignorowany.

Podobnie strict-dynamic nie jest obsługiwany przez wszystkie przeglądarki. Zalecamy ustawienie listy dozwolonych jako ustawień zastępczych dla wszystkich niezgodnych przeglądarek. Lista dozwolonych będzie ignorowana w przeglądarkach, które obsługują strict-dynamic.

Jak tworzyć rygorystyczne zasady CSP

Poniżej znajdziesz przykład użycia rygorystycznego CSP z zasadą opartą na liczbie jednorazowej.

CSP:

script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;

HTML:

<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>

random123 to dowolny ciąg znaków w formacie base64 wygenerowany po stronie serwera przy każdym wczytaniu strony. Metody unsafe-inline i https: są ignorowane w nowoczesnych przeglądarkach z powodu liczby jednorazowej i strict-dynamic. Więcej informacji na temat stosowania rygorystycznego CSP znajdziesz w przewodniku po rygorystycznym CSP.

Możesz sprawdzić CSP pod kątem potencjalnych pomijania za pomocą narzędzi Lighthouse i CSP Evaluator. Jeśli chcesz przetestować nową wersję CSP bez ryzyka uszkodzenia istniejących stron, zdefiniuj ją w trybie „tylko raporty”, używając nazwy Content-Security-Policy-Report-Only jako nagłówka. Spowoduje to wysłanie naruszeń CSP do wszystkich miejsc docelowych raportowania skonfigurowanych w report-to i report-uri, ale nie wymusza korzystania z CSP.