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

Dowiedz się, dlaczego izolacja zasobów z różnych domen jest potrzebna do korzystania z potężnych funkcji, takich jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() i wysokorozdzielczościowy minutnik o zwiększonej precyzji.

Wprowadzenie

W artykule Uzyskiwanie przez witrynę stanu „isolated” za pomocą mechanizmów COOP i COEP wyjaśniliśmy, jak zastosować stan „isolated” za pomocą mechanizmów COOP i COEP. W tym artykule dowiesz się, dlaczego izolacja od zasobów z innych domen jest wymagana do włączenia zaawansowanych funkcji w przeglądarce.

Tło

Sieć jest zbudowana na podstawie zasady tego samego pochodzenia: funkcji zabezpieczeń, która ogranicza sposób interakcji dokumentów i skryptów z zasobami z innego pochodzenia. Ta zasada ogranicza sposoby dostępu witryn do zasobów w innych domenach. Na przykład dokument z domeny https://a.example nie może uzyskać dostępu do danych hostowanych w dodatku https://b.example.

Jednak zasada dotycząca tej samej domeny miała pewne historyczne wyjątki. Każda witryna może:

  • Umieszczenie elementów iframe z różnych źródeł
  • zawierać zasoby z innych źródeł, takie jak obrazy lub skrypty;
  • Otwieranie wyskakujących okienek z dostępem do odwołania DOM w innej domenie

Gdyby można było zaprojektować sieć od podstaw, te wyjątki nie byłyby potrzebne. Niestety, zanim społeczność internetowa zdała sobie sprawę z głównych zalet rygorystycznych zasad dotyczących tego samego pochodzenia, internet już korzystał z tych wyjątków.

Skutki zaniedbania zasady tego samego pochodzenia zostały załatane na 2 sposoby. Jednym z nich było wprowadzenie nowego protokołu o nazwie współdzielenie zasobów pomiędzy serwerami z różnych domen (CORS), którego celem jest zapewnienie, że serwer zezwala na udostępnianie zasobu z określonego źródła. Drugim sposobem jest pośrednie usunięcie bezpośredniego dostępu skryptu do zasobów z innych źródeł przy zachowaniu zgodności wstecznej. Takie zasoby z innych witryn są nazywane „nieprzezroczystymi”. Dlatego np. manipulowanie pikselami obrazu z innej domeny za pomocą CanvasRenderingContext2Dnie działa, chyba że zastosowano do niego protokół CORS.

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

Grupa kontekstu przeglądania

Przez długi czas połączenie CORS i zasobów nieprzezroczystych wystarczało do zapewnienia bezpieczeństwa przeglądarek. Czasami wykryto przypadki szczególne (np. luki w zabezpieczeniach w plikach JSON), które wymagały załatania, ale ogólnie zasada nieudzielania bezpośredniego dostępu do odczytu bajtów nieprzetworzonych zasobów z innych źródeł okazała się skuteczna.

Wszystko to zmieniło się wraz z Spectre, który sprawia, że wszystkie dane załadowane do tej samej grupy kontekstu przeglądania co kod, mogą być potencjalnie odczytywalne. Na podstawie czasu trwania określonych operacji atakujący mogą zgadywać zawartość pamięci podręcznej procesora, a przez to zawartość pamięci procesu. Takie ataki na czas są możliwe dzięki dokładnym zegarom, które istnieją na platformie, ale można je przyspieszyć za pomocą precyzyjnych zegarów, zarówno jawnych (takich jak performance.now()), jak i ukrytych (takich jak SharedArrayBuffer). Jeśli evil.com umieszcza obraz z innego źródła, może użyć ataku Spectre do odczytania danych o pikselach, co spowoduje, że zabezpieczenia oparte na „przezroczystości” staną się nieskuteczne.

Spectr

W idealnej sytuacji wszystkie żądania między domenami powinny być weryfikowane przez serwer, który jest właścicielem zasobu. Jeśli serwer, który jest właścicielem zasobu, nie przeprowadzi weryfikacji, dane nigdy nie trafią do grupy kontekstu przeglądania złośliwego aktora, a w konsekwencji pozostaną poza zasięgiem wszelkich ataków Spectre, które strona internetowa mogłaby przeprowadzić. Nazywamy to stanem izolowanym od zasobów z innych domen. Właśnie o to chodzi w programie COOP+COEP.

W stanie izolacji między domenami witryna wysyłająca żądanie jest uważana za mniej niebezpieczną, co umożliwia korzystanie z potężnych funkcji, takich jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory()wysokoprecyzyjne liczniki czasu o zwiększonej dokładności, które mogłyby być wykorzystywane do ataków podobnych do Spectre. Zapobiega też modyfikowaniu wartości document.domain.

Zasady umieszczania zasobów z innych domen

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

Jak działa COEP

Aby aktywować te zasady, dodaj do dokumentu ten nagłówek HTTP:

Cross-Origin-Embedder-Policy: require-corp

Kluczowe słowo require-corp to jedyna dozwolona wartość w przypadku COEP. W ten sposób wdrażamy zasadę, że dokument może wczytywać tylko zasoby z tego samego źródła lub zasoby wyraźnie oznaczone jako wczytywane z innego źródła.

Aby zasoby mogły być ładowane z innego źródła, muszą obsługiwać mechanizm CORS lub CORP.

Mechanizm CORS

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ć crossoriginatrybut, aby załadować go na stronie internetowej bez blokowania przez COEP.

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

Jeśli na przykład ten zasób obrazu jest wyświetlany z nagłówkami CORS, użyj atrybutu crossorigin, aby żądanie pobierania zasobu używało trybu CORS. Zapobiega to też wczytywaniu obrazu, chyba że ustawiono nagłówki CORS.

Podobnie możesz pobierać dane z różnych źródeł za pomocą metody fetch(), która nie wymaga specjalnego przetwarzania, o ile serwer odpowiada z odpowiednimi nagłówkami HTTP.

Zasady dotyczące zasobów z innych domen

Zasady dotyczące zasobów z innych źródeł (Cross-Origin Resource Policy, CORP) zostały pierwotnie wprowadzone jako opcjonalne, aby chronić zasoby przed wczytywaniem przez inne źródło. W kontekście COEP CORP może określić zasady właściciela zasobu dotyczące tego, kto może wczytać zasób.

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 mogą być wczytywane tylko z tego samego źródła.

Cross-Origin-Resource-Policy: cross-origin

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

Zasady dotyczące otwierającego z innej domeny

Zasady otwierania zasobów z innych źródeł (COOP) umożliwiają zapewnienie, że okno najwyższego poziomu jest odizolowane od innych dokumentów. Dzieje się tak, ponieważ te ostatnie są umieszczane w innej grupie kontekstu przeglądania, co uniemożliwia im bezpośrednią interakcję z oknem najwyższego poziomu. Jeśli na przykład dokument z kooperacją otwiera wyskakujące okienko, jego właściwość window.opener będzie miała wartość null. Ponadto właściwość .closed odwołania do openera zwróci 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 same-origin mogą należeć do tego samego kontekstu przeglądania, co dokumenty tego samego pochodzenia, które są również wyraźnie oznaczone same-origin.

COOP

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

Dokument najwyższego poziomu z wartością same-origin-allow-popups zachowuje odwołania do wszystkich wyskakujących okienek, które nie mają ustawionej wartości COOP lub nie są objęte izolacją, ponieważ mają wartość unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

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

Podsumowanie

Jeśli chcesz mieć zagwarantowany dostęp do zaawansowanych funkcji, takich jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() czy wysoka rozdzielczość timerów z lepszą precyzją, pamiętaj, że Twój dokument musi używać zarówno parametru COEP o wartości require-corp, jak i COOP o wartości same-origin. W przeciwnym razie przeglądarka nie będzie mogła zapewnić wystarczającej izolacji, aby bezpiecznie włączyć te zaawansowane funkcje. Stan strony możesz sprawdzić, sprawdzając, czy self.crossOriginIsolated zwraca true.

Dowiedz się, jak to zrobić, z artykułu Uzyskiwanie dostępu do zasobów z innych źródeł za pomocą mechanizmów COOP i COEP.

Zasoby