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:
- COEP: zasady umieszczania zasobów z innych domen
- COOP: zasada dotycząca otwierającego z innej domeny
- CORP: zasady dotyczące zasobów z innych domen
- CORS: współdzielenie zasobów pomiędzy serwerami z różnych domen
- CORB: blokowanie odczytu z innych domen
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ą
CanvasRenderingContext2Dnie działa, chyba że do obrazu zastosowano CORS.
Wszystkie te decyzje dotyczące zasad są podejmowane w grupie kontekstu przeglądania.

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.

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.
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.

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.

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.

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.