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 za pomocą mechanizmów COOP i COEP uzyskać stan „isolated”. 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, aby 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ą CanvasRenderingContext2D
nie działa, chyba że zastosowano do niego CORS.
Wszystkie te decyzje dotyczące zasad są podejmowane w ramach grupy kontekstu przeglądania.
Przez długi czas połączenie CORS i zasobów nieprzezroczystych wystarczało do zapewnienia bezpieczeństwa przeglądarek. Czasami wykrywane były 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 wszelkie dane załadowane do tej samej grupy kontekstu przeglądania co Twój kod mogą być potencjalnie odczytane. 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.
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 podmiotu, a w konsekwencji nie będą dostępne dla żadnych 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()
i 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ą 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.
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ć crossorigin
atrybut, 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ć Twoje 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 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 wartością COOP 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
.
Nagłówek Cross-Origin-Opener-Policy
może mieć 3 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
.
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
.
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ść COOP same-origin
.
Podsumowanie
Jeśli chcesz mieć zagwarantowany dostęp do zaawansowanych funkcji, takich jak SharedArrayBuffer
,
performance.measureUserAgentSpecificMemory()
czy wysoka rozdzielczość zegara 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 źródeł za pomocą mechanizmów COOP i COEP.