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 wysoka rozdzielczość zegara z większą precyzją.

Wprowadzenie

W artykule Uzyskiwanie przez witrynę „izolacji między domenami” za pomocą zasad COOP i COEP wyjaśniliśmy, jak zastosować „izolację między domenami” za pomocą zasad 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 między domenami za pomocą odwołania do DOM

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 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 surowych bajtów zasobów z innych źródeł się sprawdziła.

Wszystko to zmieniło się wraz z Spectre, który sprawia, że wszystkie dane wczytane do tej samej grupy kontekstu przeglądania co kod, mogą być potencjalnie czytelne. 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 wykorzystać atak 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ć sprawdzane 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. Dokładnie o to chodzi w programie COOP+COEP.

W stanie izolowania 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 zostać wykorzystane 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ą 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.

Jak działa COEP

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

Cross-Origin-Embedder-Policy: require-corp

COEP przyjmuje jedną wartość require-corp. W ten sposób narzucamy 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ł (CORP) zostały pierwotnie wprowadzone jako opcjonalne, aby chronić Twoje zasoby przed wczytywaniem przez inne źródła. 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

Zasada dotycząca otwierającego z innej domeny (COOP) pozwala na zapewnienie, że okno najwyższego poziomu jest odizolowane od innych dokumentów. Dzieje się tak, gdy umieszczasz je w innej grupie kontekstu przeglądania, dzięki czemu nie mogą one bezpośrednio wchodzić w interakcje 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ą izolowane, ponieważ mają wartość unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none jest domyślną wartością i pozwala dodać dokument do grupy kontekstu przeglądania otwierającego, chyba że otwierający ma wartość współczynnika COOP same-origin.

Podsumowanie

Jeśli chcesz mieć zagwarantowany dostęp do zaawansowanych funkcji, takich jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() lub wysokorozdzielcze zegary z większą dokładnością, pamiętaj, że Twój dokument musi używać zarówno parametru COEP o wartości require-corp, jak i parametr 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 domen za pomocą nagłówka COOP i COEP.

Zasoby