Odizolowanie witryny od zasobów z innych domen za pomocą COOP i COEP

Użyj narzędzi COOP i COEP, aby skonfigurować środowisko odizolowane od zasobów z innych domen i włączyć zaawansowane funkcje, takie jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() oraz licznik czasu o wysokiej rozdzielczości, z większą precyzją.

Aktualizacje

  • 21 czerwca 2022 r.: w przypadku włączenia izolacji zasobów z innych domen należy też zachować ostrożność w przypadku skryptów instancji roboczych. Dodaliśmy wyjaśnienia.
  • 5 sierpnia 2021 r.: interfejs JS Self-Profiling API został wspomniany jako jeden z interfejsów API, które wymagają izolacji od zasobów z innych domen, ale ze względu na niedawną zmianę kierunku został usunięty.
  • 6 maja 2021 r.: na podstawie opinii i zgłoszonych problemów postanowiliśmy skorygować harmonogram korzystania z SharedArrayBuffer w żadnych witrynach i odizolowanych od zasobów z innych domen, które nie będą ograniczane w Chrome M92.
  • 16 kwietnia 2021 r.: dodaliśmy uwagi o nowym trybie COEP bez danych uwierzytelniających oraz o coOP-same-origin-allow-popups, które mają stanowić prosty warunek do izolacji użytkowników z innych domen.
  • 5 marca 2021 roku: usunęliśmy ograniczenia dotyczące funkcji SharedArrayBuffer i performance.measureUserAgentSpecificMemory() oraz funkcji debugowania, które są teraz w pełni włączone w Chrome 89. Dodaliśmy nadchodzące funkcje performance.now() i performance.timeOrigin, które będą bardziej dokładne.
  • 19 lutego 2021 r.: dodaliśmy uwagę na temat zasad funkcji allow="cross-origin-isolated" i funkcji debugowania w Narzędziach deweloperskich.
  • 15 października 2020 roku: aplikacja self.crossOriginIsolated jest dostępna w Chrome 87. W związku z tym document.domain nie można zmienić, gdy self.crossOriginIsolated zwraca wartość true. Kończy się okres próbny origin performance.measureUserAgentSpecificMemory() i jest on domyślnie włączony w Chrome 89. Bufor tablicy współdzielonej w Chrome na Androida będzie dostępny od Chrome 88.

Niektóre internetowe interfejsy API zwiększają ryzyko ataków pobocznych, takich jak Spectre. Aby ograniczyć to ryzyko, przeglądarki oferują wyizolowane środowisko, w którym użytkownik wyraził zgodę, izolowane od zasobów z innych domen. W stanie izolowanym od zasobów z innych domen strona będzie mogła korzystać z funkcji uprzywilejowanych, takich jak:

API Opis
SharedArrayBuffer Wymagane w przypadku wątków WebAssembly. Ta funkcja jest dostępna w Chrome w wersji 88 na Androidzie. Wersja na komputery jest obecnie domyślnie włączona za pomocą funkcji izolacji witryn, ale wymaga stanu izolacji od zasobów z innych domen, a w Chrome 92 jest domyślnie wyłączona.
performance.measureUserAgentSpecificMemory() Dostępna od Chrome 89.
performance.now(), performance.timeOrigin Obecnie jest on dostępny w wielu przeglądarkach, a rozdzielczość jest ograniczona do 100 mikrosekund. W przypadku izolacji zasobów z innych domen rozdzielczość może wynosić co najmniej 5 mikrosekund.
Funkcje, które będą dostępne w trybie izolowanym od zasobów z innych domen.

Stan izolowany od zasobów z innych domen zapobiega też modyfikacjom document.domain. (Możliwość zmiany document.domain umożliwia komunikację między dokumentami w tej samej witrynie i jest uznawana za lukę w zasadzie dotyczącej tego samego pochodzenia).

Aby przejść na stan izolowany od zasobów z innych domen, musisz wysłać w dokumencie głównym następujące nagłówki HTTP:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

Nagłówki te nakazują przeglądarce blokowanie wczytywania zasobów lub elementów iframe, które nie mają włączonej opcji ładowania przez dokumenty z innych domen, i uniemożliwiać oknam z innych domen bezpośrednią interakcję z dokumentem. Oznacza to również, że zasoby ładowane z innych domen wymagają zgody użytkownika.

Aby określić, czy strona jest izolowana od zasobów z innych domen, sprawdź self.crossOriginIsolated.

Z tego artykułu dowiesz się, jak z nich korzystać. W kolejnym artykule przedstawię więcej informacji i kontekst.

Wdróż COOP i COEP, aby odizolować witrynę od zasobów z innych domen

Integracja narzędzi COOP i COEP

1. Ustaw nagłówek Cross-Origin-Opener-Policy: same-origin w dokumencie najwyższego poziomu

Gdy włączysz funkcję COOP: same-origin w dokumencie najwyższego poziomu, okna o tym samym pochodzeniu oraz okna otwarte z poziomu dokumentu będą miały oddzielną grupę kontekstu przeglądania, chyba że są w tym samym źródle i mają to samo ustawienie COOP. W związku z tym dla otwartych okien wymuszana jest izolacja, a wzajemna komunikacja między obiema oknami jest wyłączona.

Grupa kontekstu przeglądania to zestaw okien, które mogą się do siebie odwoływać. Na przykład dokument najwyższego poziomu i jego dokumenty podrzędne umieszczone w elemencie <iframe>. Jeśli witryna (https://a.example) otworzy wyskakujące okienko (https://b.example), okno otwierające i wyskakujące okienko mają ten sam kontekst przeglądania, dlatego mają do siebie dostęp za pomocą interfejsów DOM API, takich jak window.opener.

Grupa kontekstu przeglądania

Możesz sprawdzić, czy narzędzie do otwierania okna i jego użytkownik znajdują się w osobnych grupach kontekstu przeglądania innych niż Narzędzia deweloperskie.

2. Sprawdź, czy zasoby mają włączony CORP lub CORS

Upewnij się, że wszystkie zasoby na stronie są wczytane z nagłówkami HTTP CORP lub CORS. Ten krok jest wymagany w kroku 4, włączając funkcję CEP.

Oto, co należy zrobić w zależności od charakteru zasobu:

  • Jeśli oczekujesz, że zasób będzie ładowany tylko z tego samego źródła, ustaw nagłówek Cross-Origin-Resource-Policy: same-origin.
  • Jeśli oczekujesz, że zasób będzie wczytywany tylko z tej samej witryny, ale z innej domeny, ustaw nagłówek Cross-Origin-Resource-Policy: same-site.
  • Jeśli zasób jest wczytywany z innych źródeł pod Twoją kontrolą, w miarę możliwości ustaw nagłówek Cross-Origin-Resource-Policy: cross-origin.
  • W przypadku zasobów z różnych domen, nad którymi nie masz kontroli:
    • Jeśli zasób jest udostępniany za pomocą CORS, użyj atrybutu crossorigin we wczytywanym tagu HTML. (na przykład <img src="***" crossorigin>).
    • Poproś właściciela zasobu o wsparcie dla CORS lub CORP.
  • W przypadku elementów iframe postępuj zgodnie z podanymi wyżej zasadami i ustaw parametr Cross-Origin-Resource-Policy: cross-origin (lub same-site, same-origin w zależności od kontekstu).
  • Skrypty wczytywane z użyciem WebWorker muszą być udostępniane z tej samej domeny, więc nie potrzebujesz nagłówków CORP ani CORS.
  • W przypadku dokumentu lub instancji roboczej udostępnianej z interfejsem COEP: require-corp zasoby podrzędne z innych domen wczytywane bez CORS muszą umożliwiać umieszczanie w nagłówku Cross-Origin-Resource-Policy: cross-origin. Dotyczy to na przykład <script>, importScripts, <link>, <video>, <iframe> itp.

3. Ocena osadzonych zasobów przy użyciu nagłówka HTTP COEP „Only Report-Only”

Przed pełnym włączeniem COEP możesz wykonać próbne uruchomienie, korzystając z nagłówka Cross-Origin-Embedder-Policy-Report-Only, aby sprawdzić, czy zasada rzeczywiście działa. Będziesz otrzymywać raporty bez blokowania umieszczonych treści.

Stosuj go rekurencyjnie do wszystkich dokumentów, w tym dokumentów najwyższego poziomu, elementów iframe i skryptów instancji roboczych. Informacje o nagłówku HTTP „Tylko raporty” znajdziesz w artykule Obserwowanie problemów przy użyciu interfejsu API do raportowania.

4. Włącz COEP

Gdy upewnisz się, że wszystko działa i że wszystkie zasoby mogą się załadować, przełącz nagłówek Cross-Origin-Embedder-Policy-Report-Only na nagłówek Cross-Origin-Embedder-Policy z tą samą wartością na wszystkie dokumenty, w tym te umieszczone w elementach iframe i skryptach instancji roboczych.

Sprawdź, czy izolacja za pomocą metody self.crossOriginIsolated powiodła się

Właściwość self.crossOriginIsolated zwraca wartość true, gdy strona jest izolowana od zasobów z innych domen, a wszystkie zasoby i okna są izolowane w tej samej grupie kontekstu przeglądania. Możesz użyć tego interfejsu API, aby sprawdzić, czy udało Ci się wyizolować grupę kontekstu przeglądania i uzyskać dostęp do zaawansowanych funkcji, takich jak performance.measureUserAgentSpecificMemory().

Debugowanie problemów przy użyciu Narzędzi deweloperskich w Chrome

W przypadku zasobów renderowanych na ekranie, takich jak obrazy, łatwo można wykryć problemy z COEP, ponieważ żądanie zostanie zablokowane, a strona wskaże brak obrazu. Jednak w przypadku zasobów, które nie mają istotnego wpływu wizualnego, np. skryptów czy stylów, problemy z COEP mogą zostać niezauważone. W tym celu użyj panelu Network (Sieć) w Narzędziach deweloperskich. Jeśli występuje problem z COEP, w kolumnie Stan powinna pojawić się wartość (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep).

Problemy dotyczące COEP w kolumnie Stan w panelu Sieć.

Następnie możesz go kliknąć, aby wyświetlić więcej szczegółów.

Szczegóły problemu dotyczącego COEP są wyświetlane na karcie Nagłówki po kliknięciu zasobu sieciowego w panelu Sieć.

Stan elementów iframe i wyskakujących okienek możesz też określić w panelu Aplikacja. Otwórz sekcję „Ramki” po lewej stronie i rozwiń opcję „top”, aby zobaczyć podział struktury zasobów.

Możesz sprawdzić stan elementu iframe, np. dostępność elementu SharedArrayBuffer itp.

Inspektor elementów iframe w Narzędziach deweloperskich w Chrome

Możesz też sprawdzić stan wyskakujących okienek, np. czy są izolowane od zasobów z innych domen.

Inspektor wyskakujących okienek w Narzędziach deweloperskich w Chrome

Obserwowanie problemów przy użyciu interfejsu API do raportowania

Interfejs API do raportowania to kolejny mechanizm, który umożliwia wykrywanie różnych problemów. Możesz skonfigurować interfejs API do raportowania w taki sposób, aby przeglądarka użytkowników wysyłała raport za każdym razem, gdy COEP zablokuje wczytanie zasobu lub COOP izoluje wyskakujące okienko. Chrome obsługuje interfejs Reporting API od wersji 69 w różnych celach, w tym COEP i COOP.

Aby dowiedzieć się, jak skonfigurować interfejs API do raportowania i serwer do otrzymywania raportów, przeczytaj artykuł Korzystanie z interfejsu API do raportowania.

Przykładowy raport dotyczący COEP

Przykładowy ładunek raportu COEP w przypadku zablokowania zasobu z innych domen wygląda tak:

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.glitch.me/check.svg?",
    "blockedURL": "https://third-party-test.glitch.me/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

Przykładowy raport dotyczący COOP

Przykładowy ładunek raportu COOP po otwarciu wyskakującego okienka wygląda tak:

[{
  "age": 7,
  "body": {
    "disposition": "enforce",
    "effectivePolicy": "same-origin",
    "nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Gdy różne grupy kontekstu przeglądania próbują się ze sobą łączyć (tylko w trybie „tylko do raportowania”), COOP wysyła też raport. Na przykład raport dotyczący próby postMessage() może wyglądać tak:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
  "age": 51785,
  "body": {
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "property": "postMessage",
    "type": "access-to-coop-page-from-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Podsumowanie

Użyj kombinacji nagłówków HTTP COOP i COEP, aby włączyć na stronie internetowej specjalny stan izolacji od zasobów z innych domen. Pozwoli Ci to sprawdzić self.crossOriginIsolated, czy strona internetowa jest izolowana od zasobów z innych domen.

Będziemy na bieżąco aktualizować ten post w miarę udostępniania nowych funkcji dla tego stanu izolowanego od zasobów z innych domen oraz wprowadzania dalszych ulepszeń w narzędziach deweloperskich dotyczących COOP i COEP.

Zasoby