Zapewnienie ochrony CSP przed atakami typu XSS

Polityka Content Security Policy (CSP) pomaga zapewnić, aby wszystkie treści wczytane na stronie były zaufane przez właściciela witryny. Dostawcy CSP ograniczają ataki typu cross-site scripting (XSS), ponieważ mogą blokować niebezpieczne skrypty wstrzykiwane przez osoby przeprowadzające atak. CSP można jednak łatwo pominąć, jeśli nie jest wystarczająco rygorystyczny. Więcej informacji znajdziesz w artykule Zminimalizowanie ryzyka ataków typu cross-site scripting (XSS) dzięki ścisłemu przestrzeganiu zasad Content Security Policy (CSP). Lighthouse zbiera zasady CSP zastosowane w dokumencie głównym i zgłasza problemy z sprawdzaniem zasad CSP, jeśli można je obejść.

Z raportu Lighthouse wynika, że w trybie egzekwowania nie znaleziono żadnego CSP.
Ostrzeżenie w raporcie Lighthouse, że w trybie egzekwowania nie znaleziono CSP.

Wymagane praktyki w przypadku CSP, którego nie można obejść

Aby mieć pewność, że CSP nie może zostać ominięta, stosuj te sprawdzone metody. Jeśli CSP można ominąć, Lighthouse wyświetli ostrzeżenie o wysokim stopniu ważności.

CSP doceluje XSS

Aby kierować reklamy na XSS, dostawca CSP powinien zawierać dyrektywę script-src, object-src i base-uri. Plik CSP powinien być też wolny od błędów składniowych.

Zabezpieczenia script-src i object-src zabezpieczają stronę przed niebezpiecznymi skryptami i wtyczkami. Za pomocą default-src można też skonfigurować ogólne zasady 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 przekierowywania wszystkich względnych adresów URL (np. skryptów) do domeny kontrolowanej przez hakera.

CSP używa liczb jednorazowych lub haszy, aby unikać pomijania listy dozwolonych

Dostawca CSP, który konfiguruje listę dozwolonych dla script-src, opiera się na założeniu, że wszystkie odpowiedzi pochodzące z zaufanej domeny są bezpieczne i mogą być wykonywane jako skrypty. Założenie to nie jest jednak prawdziwe w przypadku nowoczesnych aplikacji. Niektóre typowe, nieszkodliwe wzorce, takie jak udostępnianie interfejsów JSONPprzechowywanie kopii biblioteki AngularJS, umożliwiają atakującym obejście ograniczeń CSP.

W praktyce może to nie być oczywiste dla autorów aplikacji, ale większość list dozwolonych (script-src) może zostać obchodząca przez osobę przeprowadzającą atak z błędem XSS i zapewniając niewielką ochronę przed wstrzykiwaniem skryptów. Z kolei metody oparte na losowych ciągach znaków i metody oparte na haszowaniu nie mają tych problemów i ułatwiają stosowanie oraz utrzymywanie bardziej bezpiecznych zasad.

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ąć obejścia, dostawca usług szyfrowania po stronie klienta powinien zezwalać na poszczególne skrypty za pomocą liczb jednorazowych lub haszy oraz używać dyrektywy „strict-dynamic” zamiast listy dozwolonych.

Dodatkowe zalecenia dotyczące bezpiecznego CSP

Aby zwiększyć bezpieczeństwo i zgodność, zaimplementuj poniższe metody. Jeśli dostawca CSP nie zastosuje się do któregokolwiek z zaleceń, Lighthouse wyświetli ostrzeżenie o średnim poziomie ważności.

Skonfiguruj raportowanie CSP

Skonfigurowanie miejsca docelowego raportowania pomoże Ci monitorować, czy nie występują awarie. Miejsce docelowe raportowania możesz ustawić za pomocą dyrektyw report-uri lub report-to. report-to nie jest obecnie obsługiwany przez wszystkie nowoczesne przeglądarki, więc zalecamy używanie obu lub tylko języka report-uri.

Jeśli jakakolwiek treść narusza zasady CSP, przeglądarka wyśle zgłoszenie do skonfigurowanego miejsca docelowego. Upewnij się, że w tym miejscu docelowym masz skonfigurowaną aplikację, która obsługuje te raporty.

Zdefiniuj CSP w nagłówku HTTP

CSP można zdefiniować w metatagu w taki 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 kodu przed metatagiem ominie CSP. Oprócz tego dostawcy CSP z metatagami nie obsługują tych atrybutów: frame-ancestors, sandbox ani raportowania.

Sprawdź, czy CSP jest zgodny wstecznie

Nie wszystkie przeglądarki obsługują liczby jednorazowe/hasze CSP, dlatego zalecamy dodanie parametru unsafe-inline jako kreacji zastępczej dla niezgodnych przeglądarek. Jeśli przeglądarka obsługuje liczby jednorazowe lub hasze, dyrektywa unsafe-inline zostanie zignorowana.

Podobnie strict-dynamic nie jest obsługiwana we wszystkich przeglądarkach. Zalecamy ustawienie listy dozwolonych jako zastępczej dla wszystkich niezgodnych przeglądarek. Lista dozwolonych adresów będzie ignorowana w przeglądarkach, które obsługują strict-dynamic.

Jak utworzyć ścisłe zasady CSP

Poniżej przedstawiamy przykład stosowania rygorystycznych zasad CSP z zasadami opartymi na szyfrach jednorazowych.

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>

Parametr random123 to dowolny ciąg znaków w formacie base64 wygenerowany po stronie serwera przy każdym wczytaniu strony. W nowoczesnych przeglądarkach metody unsafe-inlinehttps: są ignorowane z powodu wartości jednorazowych i strict-dynamic. Więcej informacji o wdrażaniu rygorystycznych zasad CSP znajdziesz w przewodniku dotyczącym rygorystycznych zasad CSP.

Aby sprawdzić, czy CSP można obejść, możesz użyć Lighthouse i sprawdzalni CSP. Jeśli chcesz przetestować nowy CSP bez ryzyka uszkodzenia istniejących stron, zdefiniuj CSP w trybie tylko do raportowania, używając jako nazwy nagłówka wartości Content-Security-Policy-Report-Only. Spowoduje to wysłanie naruszeń zasad CSP do wszystkich miejsc docelowych raportowania skonfigurowanych za pomocą parametrów report-to i report-uri, ale nie spowoduje wymuszenia zasad CSP.