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

Dowiedz się, dlaczego izolacja zasobów z innych domen jest potrzebna do korzystania z większej precyzji w korzystaniu z zaawansowanych funkcji, takich jak SharedArrayBuffer i performance.measureUserAgentSpecificMemory(), oraz licznika czasu wysokiej rozdzielczości.

Wstęp

W artykule Zapewnianie izolacji witryn od zasobów z innych domen przy użyciu narzędzi COOP i COEP wyjaśniliśmy, jak za pomocą COOP i COEP wprowadzić zmiany w środowisku odizolowanym od zasobów z innych domen. Z tego artykułu dowiesz się, dlaczego izolacja zasobów z innych domen jest wymagana do włączenia zaawansowanych funkcji w przeglądarce.

Wprowadzenie

Sieć opiera się na zasadach dotyczących tego samego pochodzenia, czyli funkcji zabezpieczeń, która ogranicza możliwość interakcji dokumentów i skryptów z zasobami z innych źródeł. Ta zasada ogranicza sposób, w jaki witryny mogą korzystać z zasobów z innych domen. Na przykład dokument z domeny https://a.example nie ma dostępu do danych przechowywanych na serwerze https://b.example.

Jednak w przypadku tej samej domeny występowały wyjątki historyczne. Każda witryna może:

  • Umieszczanie elementów iframe z innych domen
  • Uwzględnij zasoby z innych domen, takie jak obrazy lub skrypty
  • Otwieraj wyskakujące okienka z innych domen z odwołaniem do DOM

Gdyby internet można było zaprojektować od podstaw, takie wyjątki nie istniały. Niestety, zanim społeczność internetowa zdała sobie sprawę z najważniejszych korzyści z zasad dotyczących tej samej domeny, korzystała już z tych wyjątków.

Skutki uboczne związane z bezpieczeństwem takiej mało restrykcyjnej zasady dotyczącej tego samego pochodzenia zostały naprawione w 2 sposoby. Jednym ze sposobów było wprowadzenie nowego protokołu o nazwie CORS, którego zadaniem jest dopilnowanie, aby serwer umożliwiał udostępnianie zasobu z określonym źródłem. Drugim sposobem jest niejawne usunięcie bezpośredniego dostępu do skryptów z zasobów z różnych domen przy zachowaniu zgodności wstecznej. Takie zasoby z innych domen są nazywane zasobami „nieprzezroczystymi”. Na przykład dlatego manipulowanie pikselami obrazu z innych domen za pomocą CanvasRenderingContext2D kończy się niepowodzeniem, jeśli nie jest do niego stosowany CORS.

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

Grupa kontekstu przeglądania

Przez długi czas połączenie CORS z nieprzezroczystymi zasobami wystarczało, aby przeglądarki były bezpieczne. Czasami wykrywane były przypadki skrajne (np. luki w zabezpieczeniach JSON) i wymagały one poprawek, jednak ogólna zasada nie zezwalania na bezpośredni dostęp do nieprzetworzonych bajtów zasobów z innych domen była skuteczna.

Wszystko to uległo zmianie w przypadku platformy Spectre, która tworzy wszelkie dane wczytywane do tej samej grupy kontekstu przeglądania, co Twój kod, co jest potencjalnie możliwe do odczytania. Mierząc czas potrzebny na określone operacje, hakerzy mogą odgadnąć zawartość pamięci podręcznej procesora, a tym samym zawartość pamięci procesu. Takie ataki czasowe są możliwe przy użyciu dostępnych na platformie liczników czasu o niskiej szczegółowości, ale można je przyspieszyć za pomocą liczników czasu o dużej szczegółowości, zarówno bezpośrednich (np. performance.now()), jak i niejawnych (np. SharedArrayBuffer). Jeśli evil.com umieszcza obraz z innych domen, może użyć ataku Spectre do odczytania danych piksela, przez co zabezpieczenia oparte na „przejrzystości” są nieskuteczne.

Widmo

W idealnej sytuacji wszystkie żądania z innych domen powinny być bezpośrednio zweryfikowane przez serwer, do którego należy zasób. Jeśli serwer będący właścicielem zasobów nie przeprowadzi weryfikacji, dane nie trafią do grupy przestępczej przeglądania, do której należą złe akty i będą niedostępne dla wszelkich ataków Spectre, które mogłyby przeprowadzić na stronie internetowej. Nazywamy to stanem izolowanym od zasobów z innych domen. Właśnie o to chodzi w firmie COOP+COEP.

W stanie izolowanym od zasobów z innych domen witryna wysyłająca żądanie jest uważana za mniej niebezpieczną, co odblokowuje zaawansowane funkcje, takie jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() i liczniki czasu w wysokiej rozdzielczości z większą precyzją, co w przeciwnym razie mogłoby być wykorzystywane do ataków typu Spectre. Zapobiega też modyfikowaniu document.domain.

Zasady dotyczące umieszczania elementów z innych domen

Zasada umieszczania danych z innych domen (COEP) uniemożliwia dokumentowi wczytywanie zasobów z innych domen, które nie przyznają wprost uprawnień do dokumentu (przy użyciu CORP lub CORS). Dzięki tej funkcji można zadeklarować, że dokument nie może wczytać takich zasobów.

Jak działa CEP

Aby aktywować tę zasadę, dołącz do dokumentu następujący nagłówek HTTP:

Cross-Origin-Embedder-Policy: require-corp

Jedyną akceptowaną wartością w przypadku COEP jest słowo kluczowe require-corp. Wymusza zasadę, zgodnie z którą dokument może ładować tylko zasoby z tego samego źródła lub zasoby wyraźnie oznaczone jako możliwe do wczytania z innego źródła.

Aby zasoby mogły być ładowane z innego źródła, muszą obsługiwać zasady udostępniania zasobów między serwerami (CORS) lub CORP.

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

Jeśli zasób z różnych domen obsługuje udostępnianie zasobów w różnych źródłach (CORS), możesz użyć atrybutu crossorigin, aby wczytać go na stronę internetową 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żyło trybu CORS. Ponadto obraz nie zostanie wczytany, chyba że ustawisz nagłówki CORS.

Dane z innych domen możesz też pobierać za pomocą metody fetch(), która nie wymaga specjalnej obsługi, o ile serwer odpowiada odpowiednim nagłówkiem HTTP.

Zasada dotycząca zasobów z innych źródeł

Zasada dotycząca zasobów krzyżowych (CORP) została wprowadzona po raz pierwszy, aby chronić zasoby przed ładowaniem z innego źródła. W kontekście COEP CORP może określić zasadę właściciela zasobów, która określa, kto może je ładować.

Nagłówek Cross-Origin-Resource-Policy może mieć 3 możliwe 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 ładować tylko z tego samego źródła.

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 razem z COEP).

Zasady otwierające połączenia z innych źródeł

Zasada otwierająca z innych domen (COOP) zapewnia odizolowanie okna najwyższego poziomu od innych dokumentów przez umieszczenie ich w innej grupie kontekstu przeglądania, przez co nie będzie ono mogło bezpośrednio korzystać z okna najwyższego poziomu. Jeśli na przykład w dokumencie z COOP otworzy się wyskakujące okienko, jego właściwość window.opener będzie miała wartość null. Ponadto właściwość .closed odwołania do niego zwraca wartość true.

COOP

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

Cross-Origin-Opener-Policy: same-origin

Dokumenty oznaczone jako same-origin mogą korzystać z tej samej grupy kontekstu przeglądania z dokumentami z tego samego pochodzenia, które są również wyraźnie oznaczone jako same-origin.

COOP

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

Dokument najwyższego poziomu z atrybutem same-origin-allow-popups zawiera odwołania do wyskakujących okienek, które nie ustawiają współpracy w innym systemie lub pozwalają wyłączyć izolację współpracy, ustawiając ją na unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

Domyślnym ustawieniem jest unsafe-none i umożliwia dodanie dokumentu do grupy kontekstu przeglądania, w którym otwiera się jego strona, chyba że sam element otwierający ma COOP o wartości same-origin.

Podsumowanie

Jeśli chcesz mieć gwarantowany dostęp z większą precyzją do zaawansowanych funkcji, takich jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() czy minutniki w wysokiej rozdzielczości, pamiętaj, że dokument musi używać funkcji COEP z wartością require-corp i COOP z wartością same-origin. W przypadku braku żadnej z tych opcji przeglądarka nie zagwarantuje wystarczającej izolacji do bezpiecznego włączenia tych zaawansowanych funkcji. Aby określić sytuację, sprawdź, czy self.crossOriginIsolated zwraca wartość true.

Instrukcje implementacji znajdziesz w artykule na temat izolowania witryny z innych domen za pomocą narzędzi COOP i COEP.

Zasoby