Dlaczego zaawansowane funkcje są potrzebne do obsługi zasobów z innych domen

Opublikowano: 4 maja 2020 r.

W artykule Zabezpieczanie witryny za pomocą COOP i COEP wyjaśniliśmy, jak przejść do stanu „witryna izolowana od zasobów z innych domen” za pomocą COOP i COEP. Ten artykuł uzupełniający wyjaśnia, dlaczego izolacja od zasobów z innych domen jest wymagana, aby włączyć zaawansowane funkcje w przeglądarce.

Słowniczek

W tym dokumencie używamy wielu podobnie nazwanych i skróconych terminów. Aby uniknąć nieporozumień, przygotowaliśmy mini słowniczek:

Tło

Internet opiera się na zasadach dotyczących tej samej domeny, czyli funkcji zabezpieczeń, która ogranicza sposób, w jaki dokumenty i skrypty mogą wchodzić w interakcje z zasobami z innej domeny. Ta zasada ogranicza sposoby, w jakie witryny mogą uzyskiwać dostęp do zasobów współdzielenia. Na przykład dokument z adresu https://a.example nie może uzyskiwać dostępu do danych hostowanych pod adresem https://b.example.

Zasady dotyczące tej samej domeny miały jednak pewne historyczne wyjątki. Każda witryna może:

  • umieszczać elementy iframe współdzielenia
  • uwzględniać zasoby współdzielenia, takie jak obrazy lub skrypty,
  • otwierać okna dialogowe z innych domen z odwołaniem do DOM.

Gdy społeczność internetowa zdała sobie sprawę z korzyści płynących z rygorystycznych zasad dotyczących tej samej domeny, internet już opierał się na tych wyjątkach.

Skutki uboczne tak liberalnych zasad dotyczących tej samej domeny zostały załatane na 2 sposoby:

  • Protokół współdzielenia zasobów pomiędzy serwerami z różnych domen (CORS) zapewnia, że serwer zezwala na udostępnianie zasobu danej domenie.
  • Deweloperzy niejawnie usuwają bezpośredni dostęp skryptów do zasobów współdzielenia, zachowując przy tym zgodność wsteczną. Takie zasoby współdzielone są nazywane zasobami „nieprzezroczystymi”. Dlatego manipulowanie pikselami z innych domen za pomocą CanvasRenderingContext2D nie działa, chyba że do obrazu zastosowano CORS.

Wszystkie te decyzje dotyczące zasad są podejmowane w grupie kontekstu przeglądania.

Grupa kontekstów przeglądania obejmuje witrynę główną i komponenty z witryny zagnieżdżonej.

Przez długi czas ta kombinacja wystarczała do zapewnienia bezpieczeństwa przeglądarek, z ograniczoną liczbą przypadków brzegowych, które wymagały bezpośredniego załatania (np. luki w zabezpieczeniach JSON).

Zmieniło się to wraz z Spectre, który sprawia, że wszystkie dane wczytywane do tej samej grupy kontekstu przeglądania co Twój kod mogą być potencjalnie czytelne. Mierząc czas wykonywania określonych operacji, atakujący mogą odgadnąć zawartość pamięci podręcznej procesora, a tym samym zawartość pamięci procesu. Takie ataki są możliwe dzięki timerom o niskiej szczegółowości, które są dostępne na platformie, i można je przyspieszyć za pomocą timerów o wysokiej szczegółowości, zarówno jawnych (np. performance.now()), jak i niejawnych (np. SharedArrayBuffer).

Jeśli evil.com umieści obraz z innej domeny, może użyć ataku Spectre, aby odczytać dane pikseli umieszczonego obrazu. Sprawia to, że zabezpieczenia oparte na „nieprzezroczystości” są nieskuteczne.

Evil.com to główna witryna, która atakuje osadzone ramki iframe i obrazy w b.example za pomocą Spectre.

Idealnie byłoby, gdyby wszystkie żądania współdzielenia były sprawdzane przez serwer, który jest właścicielem zasobu. Jeśli weryfikacja nie została przeprowadzona, dane nie powinny nigdy trafić do grupy kontekstu przeglądania złośliwego użytkownika. Dzięki temu dane pozostają poza zasięgiem potencjalnych ataków Spectre. Nazywamy to stanem izolacji od zasobów z innych domen.

Gdy umieszczony kod jest w stanie izolacji od zasobów z innych domen, witryna wysyłająca żądanie jest uważana za mniej niebezpieczną. Umożliwia to witrynie wysyłającej żądanie używanie SharedArrayBuffer, performance.measureUserAgentSpecificMemory() i timerów o wysokiej rozdzielczości z większą precyzją, a jednocześnie zapobiega potencjalnym atakom Spectre. Ten stan uniemożliwia też modyfikowanie document.domain.

Zasady umieszczania zasobów z innych domen

Zasady umieszczania zasobów ze współdzielonych domen (COEP) uniemożliwiają dokumentowi wczytywanie zasobów ze współdzielonych domen, które nie przyznają mu wyraźnie uprawnień za pomocą CORP lub CORS. Dzięki tej funkcji możesz zadeklarować, że dokument nie może wczytywać takich zasobów.

Diagram pokazujący, które osadzone zasoby są dozwolone, a które niedozwolone ze względu na zasady CORP.
Witryna nadrzędna, a.example, ustawiła zasadę COEP na require-corp. a.example chce umieścić 3 zasoby z b.example, ale tylko 2 z nich się udało. 2 udane umieszczenia obejmują plik JavaScript z zasadami CORP z innych domen i obraz z dozwolonym CORS. Trzeci zasób to film, który ma zasady CORP wymagające, aby zasób był umieszczony tylko w tej samej domenie, dlatego film nie zostanie wczytany w a.example.

Aby aktywować tę zasadę, dodaj do dokumentu ten nagłówek HTTP:

Cross-Origin-Embedder-Policy: require-corp

COEP przyjmuje tylko jedną wartość: require-corp. Wymusza to zasadę, że dokument może wczytywać tylko zasoby z tej samej domeny lub zasoby wyraźnie oznaczone jako możliwe do wczytania z innej domeny.

Aby zasoby można było wczytywać z innej domeny, muszą one obsługiwać współdzielenie zasobów pomiędzy serwerami z różnych domen (CORS) lub zasady dotyczące zasobów z innych domen (CORP).

Współdzielenie zasobów pomiędzy serwerami z różnych domen

Jeśli zasób z innej domeny obsługuje współdzielenie zasobów pomiędzy serwerami z różnych domen (CORS), możesz użyć crossorigin atrybutu , aby wczytać go na stronę bez blokowania przez COEP.

<img src="https://third-party.example.com/image.jpg" crossorigin>

Jeśli na przykład ten zasób obrazu jest udostępniany z nagłówkami CORS, użyj atrybutu crossorigin, aby żądanie pobrania zasobu używało trybu CORS. Uniemożliwia to też wczytywanie obrazu, chyba że ustawia on nagłówki CORS.

Podobnie możesz pobierać dane z innych domen za pomocą metody fetch(), która nie wymaga specjalnego postępowania, o ile serwer odpowiada z odpowiednimi nagłówkami HTTP.

Zasady dotyczące zasobów z innych domen

Zasady dotyczące zasobów z innych domen (CORP) zostały pierwotnie wprowadzone jako opcja, która chroni zasoby przed wczytywaniem przez inną domenę. W kontekście COEP zasady CORP mogą określać zasady właściciela zasobu dotyczące tego, kto może wczytywać zasób.

Nagłówek Cross-Origin-Resource-Policy może przyjmować 3 wartości:

Cross-Origin-Resource-Policy: same-site

Zasoby oznaczone jako same-site można wczytywać tylko z tej samej witryny.

Cross-Origin-Resource-Policy: same-origin

Zasoby oznaczone jako same-origin można wczytywać tylko z tej samej domeny.

Cross-Origin-Resource-Policy: cross-origin

Zasoby oznaczone jako cross-origin mogą być wczytywane przez dowolną witrynę. (Ta wartość została dodana do specyfikacji CORP wraz z COEP).

Zasada dotycząca otwierającego z innej domeny

Zasada dotycząca otwierającego z innej domeny (COOP) umożliwia izolowanie okna najwyższego poziomu od innych dokumentów przez umieszczenie dokumentów w osobnej grupie kontekstu przeglądania. W ten sposób dokumenty nie mogą bezpośrednio wchodzić w interakcje z oknem najwyższego poziomu. Jeśli na przykład dokument z COOP otworzy okno dialogowe, jego właściwość window.opener będzie mieć wartość null. Właściwość .closed odwołania do otwierającego ma wartość true.

Nie udało się otworzyć strony a.example w oknie b.example.

Nagłówek Cross-Origin-Opener-Policy może przyjmować 3 wartości:

Cross-Origin-Opener-Policy: same-origin

Dokumenty oznaczone jako same-origin mogą współdzielić tę samą grupę kontekstu przeglądania z dokumentami z tej samej domeny, które są również wyraźnie oznaczone jako same-origin.

Ilustracja przedstawiająca okno, które może wchodzić w interakcję z wyskakującym okienkiem „same-origin” należącym do tej samej grupy kontekstów przeglądania, ale nie jest oznaczone jako „same-origin”, a jednocześnie znajduje się poza grupą kontekstów przeglądania.

Cross-Origin-Opener-Policy: same-origin-allow-popups

Dokument najwyższego poziomu z same-origin-allow-popups zachowuje odniesienia do wszystkich swoich wyskakujących okienek, które nie ustawiają COOP lub które rezygnują z izolacji przez ustawienie COOP na unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none jest wartością domyślną i umożliwia dodanie dokumentu do grupy kontekstu przeglądania otwierającego, chyba że sam otwierający ma COOP o wartości same-origin.

Podsumowanie

Jeśli chcesz mieć dostęp do funkcji takich jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory(), czy timery o wysokiej rozdzielczości z większą precyzją, Twój dokument musi używać zarówno COEP z wartością require-corp jak i COOP z wartością same-origin. W przypadku braku jednego z nich przeglądarka nie zagwarantuje wystarczającej izolacji, aby bezpiecznie włączyć te zaawansowane funkcje. Sytuację na stronie możesz sprawdzić, sprawdzając, czy self.crossOriginIsolated zwraca wartość true.

Dowiedz się, jak to zrobić, w artykule Zabezpieczanie witryny za pomocą COOP i COEP.

Zasoby