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

Użyj COOP i COEP, aby skonfigurować środowisko odizolowane między domenami i włączyć zaawansowane funkcje, takie jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() i minutnik o wysokiej rozdzielczości z większą precyzją.

Nowości

  • 21 czerwca 2022 r.: skrypty workerów również wymagają ostrożności, gdy włączona jest izolacja między domenami. Dodano wyjaśnienia.
  • 5 sierpnia 2021 r.: interfejs JS Self-Profiling API został wymieniony jako jeden z interfejsów API, które wymagają izolacji między domenami, ale w związku z niedawną zmianą kierunku został usunięty.
  • 6 maja 2021 roku: na podstawie opinii i raportowanych problemów zdecydowaliśmy się zmienić harmonogram ograniczania korzystania z funkcji SharedArrayBuffer w witrynach bez izolacji zasobów z innych domen w Chrome M92.
  • 16 kwietnia 2021 r.: dodano informacje o nowym trybie COEP bez uwierzytelnianiaCOOP same-origin-allow-popups jako złagodzeniu warunku izolacji między domenami.
  • 5 marca 2021 r.: usunęliśmy ograniczenia dotyczące funkcji SharedArrayBuffer, performance.measureUserAgentSpecificMemory() i debugowania, które są teraz w pełni włączone w Chrome 89. Dodano nadchodzące funkcje performance.now() i performance.timeOrigin, które będą miały większą dokładność.
  • 19 lutego 2021 r.: dodano informację o zasadach dotyczących funkcjiallow="cross-origin-isolated" oraz funkcje debugowania w Narzędziach deweloperskich.
  • 15 października 2020 r.: self.crossOriginIsolated jest dostępna w Chrome 87. W związku z tym document.domain jest niezmienny, gdy self.crossOriginIsolated zwraca wartość true. performance.measureUserAgentSpecificMemory() kończy testowanie pochodzenia i jest domyślnie włączony w Chrome 89. Udostępniony bufor tablic w Chrome na Androida będzie dostępny od wersji 88.

Niektóre interfejsy API zwiększają ryzyko ataków typu side-channel, takich jak Spectre. Aby ograniczyć to ryzyko, przeglądarki oferują odizolowane środowisko oparte na opcjonalnym zgłaszaniu, zwane izolacją zasobów z innych domen. W stanie odizolowania między domenami strona internetowa może korzystać z funkcji uprzywilejowanych, takich jak:

Interfejs API Opis
SharedArrayBuffer Wymagane w przypadku wątków WebAssembly. Funkcja jest dostępna w Chrome 88 na Androida. Wersja na komputery jest obecnie domyślnie włączona za pomocą izolacji witryn, ale wymaga izolowania zasobów z innych domen. W Chrome 92 będzie domyślnie wyłączona.
performance.measureUserAgentSpecificMemory() Dostępna od wersji Chrome 89.
performance.now(), performance.timeOrigin Obecnie jest dostępna w wielu przeglądarkach z rozdzielczością ograniczoną do 100 mikrosekund lub wyższą. W przypadku izolacji między domenami rozdzielczość może wynosić co najmniej 5 mikrosekund.
Funkcje, które będą dostępne w stanie izolowanym od zasobów z innych domen.

Stan izolowany od zasobów z innych domen zapobiega też modyfikacjom document.domain. (Możliwość zmiany wartości document.domain umożliwia komunikację między dokumentami w tej samej witrynie i była uważana za lukę w zasadach dotyczących tej samej domeny).

Aby włączyć izolację zasobów z innych domen, musisz wysłać te nagłówki HTTP w dokumencie głównym:

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

Te nagłówki instruują przeglądarkę, aby blokowała wczytywanie zasobów lub ramek iframe, które nie zostały załadowane przez dokumenty z innych źródeł, oraz uniemożliwiała oknom z innych źródeł bezpośrednią interakcję z Twoim dokumentem. Oznacza to też, że zasoby wczytywane z innych domen wymagają zgody użytkownika.

Aby sprawdzić, czy strona internetowa jest izolowana od zasobów z innych domen, użyj przeglądarki self.crossOriginIsolated.

Z tego artykułu dowiesz się, jak używać tych nowych nagłówków. W następnym artykule przedstawię więcej informacji o tym temacie.

Wdróż COOP i COEP, aby odizolować witrynę od innych źródeł

Integracja z COOP i COEP

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

Po włączeniu COOP: same-origin w dokumencie najwyższego poziomu okna z tą samą domeną i okna otwarte z tego dokumentu będą mieć osobną grupę kontekstu przeglądania, chyba że znajdują się w tej samej domenie z tym samym ustawieniem COOP. W związku z tym izolacja jest wymuszana w przypadku otwartych okien, a wzajemna komunikacja między nimi jest wyłączona.

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

Grupa kontekstu przeglądania

Możesz sprawdzić, czy okno otwierające i okno otwarte znajdują się w oddzielnych grupach kontekstu przeglądania w Narzędziach deweloperskich.

2. Upewnij się, że zasoby mają włączone CORP lub CORS

Upewnij się, że wszystkie zasoby na stronie są wczytywane za pomocą nagłówków CORP lub CORS HTTP. Ten krok jest wymagany do wykonania kroku 4, czyli włączenia COEP.

W zależności od rodzaju zasobu musisz wykonać jedną z tych czynności:

  • Jeśli zasób ma być wczytywany tylko z tego samego źródła, ustaw nagłówek Cross-Origin-Resource-Policy: same-origin.
  • Jeśli zasób ma być 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 domen, na które masz kontrolę, w miarę możliwości ustaw nagłówek Cross-Origin-Resource-Policy: cross-origin.
  • W przypadku zasobów między domenami, nad którymi nie masz kontroli:
    • Jeśli zasób jest udostępniany za pomocą CORS, użyj atrybutu crossorigin w tagu HTML ładowania. (na przykład <img src="***" crossorigin>).
    • Poproś właściciela zasobu o wsparcie CORS lub CORP.
  • W przypadku tagów iframe postępuj zgodnie z tymi samymi zasadami i ustaw wartość Cross-Origin-Resource-Policy: cross-origin (lub same-site, same-origin w zależności od kontekstu).
  • Skrypty wczytane za pomocą WebWorker muszą być dostarczane z tego samego źródła, więc nie potrzebujesz nagłówków CORP ani CORS.
  • W przypadku dokumentu lub pracownika obsługiwanego przez COEP: require-corp, załadowane bez CORS zasoby podrzędne z innej domeny muszą mieć ustawiony nagłówek Cross-Origin-Resource-Policy: cross-origin, aby umożliwić ich umieszczanie. Dotyczy to na przykład znaczników <script>, importScripts, <link>, <video>, <iframe> itp.

3. Używanie nagłówka HTTP COEP Report-Only do oceny zasobów wbudowanych

Zanim w pełni włączysz COEP, możesz przeprowadzić test działania, używając nagłówka Cross-Origin-Embedder-Policy-Report-Only, aby sprawdzić, czy zasady rzeczywiście działają. Będziesz otrzymywać raporty bez blokowania treści wstawionych.

Zastosować to rekurencyjnie do wszystkich dokumentów, w tym dokumentu najwyższego poziomu, ramek iframe i skryptów workera. Informacje o nagłówku HTTP „Tylko raportowanie” znajdziesz w artykule Obserwowanie problemów za pomocą interfejsu API do raportowania.

4. Włączanie COEP

Gdy potwierdzisz, że wszystko działa i wszystkie zasoby zostały pomyślnie załadowane, zmień nagłówek Cross-Origin-Embedder-Policy-Report-Only na nagłówek Cross-Origin-Embedder-Policy z tą samą wartością we wszystkich dokumentach, w tym w tych, które są osadzone za pomocą ramek iframe i skryptów workera.

Sprawdzanie, czy izolacja się powiodła za pomocą self.crossOriginIsolated

Właściwość self.crossOriginIsolated zwraca wartość true, gdy strona internetowa jest w stanie izolacji między domenami, a wszystkie zasoby i okna są izolowane w ramach tej samej grupy kontekstu przeglądania. Za pomocą tego interfejsu API możesz sprawdzić, czy udało Ci się wyodrębnić grupę kontekstu przeglądania i uzyskać dostęp do zaawansowanych funkcji, takich jak performance.measureUserAgentSpecificMemory().

Debugowanie problemów za pomocą Narzędzi deweloperskich w Chrome

W przypadku zasobów renderowanych na ekranie, takich jak obrazy, wykrycie problemów z zasadami COEP jest dość łatwe, ponieważ żądanie zostanie zablokowane, a strona wskaże brakujący obraz. Jednak w przypadku zasobów, które nie mają wpływu na wygląd, takich jak skrypty czy style, problemy związane z COEP mogą pozostać niezauważone. W takich przypadkach użyj panelu Sieć w Narzędziach dla deweloperów. Jeśli wystąpił problem z COEP, w kolumnie Stan zobaczysz wartość (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep).

problemy z COEP w kolumnie Stan w panelu Sieć.

Możesz wtedy kliknąć wpis, aby wyświetlić więcej szczegółów.

Szczegóły problemu z COEP są widoczne na karcie Nagłówki po kliknięciu zasobu sieciowego w panelu Sieć.

Stan ramek iframe i okienek wyskakujących możesz też sprawdzić w panelu Aplikacja. Otwórz sekcję „Ramki” po lewej stronie i rozwiń „góra”, aby zobaczyć strukturę zasobów.

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

inspektor iframe w Narzędziach deweloperskich w Chrome

Możesz też sprawdzić stan wyskakujących okienek, np. czy są one odizolowane między domenami.

inspektor okna wyskakującego w Narzędziach deweloperskich w Chrome

Obserwowanie problemów za pomocą interfejsu Reporting API

Interfejs Reporting API to kolejny mechanizm, za pomocą którego możesz wykrywać różne problemy. Możesz skonfigurować interfejs API do raportowania, aby instruować przeglądarkę użytkowników o wysyłaniu raportu, gdy COEP zablokuje wczytywanie zasobu lub COOP odizoluje wyskakujące okienko. Od wersji 69 Chrome obsługuje interfejs Reporting API do różnych celów, w tym do korzystania z COEP i COOP.

Aby dowiedzieć się, jak skonfigurować interfejs API do raportowania i ustawić serwer do odbierania raportów, zapoznaj się z artykułem Korzystanie z interfejsu API do raportowania.

Przykładowy raport COEP

Przykład ładunku raportu COEP, gdy zasób między domenami jest zablokowany, 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 COOP

Przykład ładunku raportu COOP, gdy wyskakujące okienko jest otwarte w trybie izolowanym, 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ą uzyskać dostęp do siebie nawzajem (tylko w trybie „tylko raporty”), COOP wysyła też raport. Na przykład raport, gdy próba wykonania operacji postMessage() się nie powiedzie, będzie 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 ustawić stronę internetową w specjalnym stanie odizolowania między domenami. Możesz sprawdzić self.crossOriginIsolated, aby określić, czy strona internetowa jest w stanie izolacji między domenami.

Będziemy aktualizować ten post w miarę udostępniania nowych funkcji w ramach izolowanego stanu między domenami oraz wprowadzania kolejnych ulepszeń DevTools w zakresie zasad COOP i COEP.

Zasoby