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

Użyj COOP i COEP, aby skonfigurować środowisko izolowane od innych domen i włączyć zaawansowane funkcje, takie jak SharedArrayBuffer, performance.measureUserAgentSpecificMemory() i timer o wysokiej rozdzielczości z większą precyzją.

Nowości

  • 21 czerwca 2022 r.: skrypty robocze również wymagają uwagi, gdy włączona jest izolacja między źródłami. Dodano kilka wyjaśnień.
  • 5 sierpnia 2021 r.: interfejs JS Self-Profiling API został wymieniony jako jeden z interfejsów API, które wymagają izolacji między źródłami, ale w związku z ostatnią zmianą kierunku został usunięty.
  • 6 maja 2021 r.: na podstawie opinii i zgłoszonych problemów zdecydowaliśmy się dostosować harmonogram ograniczenia użycia SharedArrayBuffer w witrynach bez izolacji zasobów z innych domen. Zostanie ono wprowadzone w Chrome M92.
  • 16 kwietnia 2021 roku: dodaliśmy uwagi dotyczące nowego trybu COEP bez danych logowaniaCOOP same-origin-allow-popups jako mniej rygorystycznego 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. Dodaliśmy nadchodzące funkcje performance.now()performance.timeOrigin, które będą miały większą precyzję.
  • 19 lutego 2021 r.: dodano notatkę o zasadach dotyczących funkcji allow="cross-origin-isolated" i funkcji debugowania w Narzędziach deweloperskich.
  • 15 października 2020 r.: self.crossOriginIsolated jest dostępny w Chrome w wersji 87. W związku z tym wartość document.domain jest niezmienna, gdy funkcja self.crossOriginIsolated zwraca wartość true. performance.measureUserAgentSpecificMemory() kończy okres próbny i jest domyślnie włączony w Chrome 89. Shared Array Buffer w Chrome na Androida będzie dostępny od wersji 88.

Niektóre interfejsy API sieci zwiększają ryzyko ataków typu side-channel, takich jak Spectre. Aby ograniczyć to ryzyko, przeglądarki oferują środowisko izolowane oparte na zasadzie rezygnacji, zwane izolacją zasobów z innych domen. W stanie izolacji od innych domen strona internetowa będzie mogła korzystać z funkcji uprzywilejowanych, takich jak:

Interfejs API Opis
SharedArrayBuffer Wymagane w przypadku wątków WebAssembly. Jest ona dostępna w Chrome 88 na Androidzie. Wersja na komputery jest obecnie domyślnie włączona dzięki izolacji witryn, ale będzie wymagać stanu izolacji zasobów z innych domen i  zostanie domyślnie wyłączona w Chrome 92.
performance.measureUserAgentSpecificMemory() Dostępne od Chrome 89.
performance.now(), performance.timeOrigin Obecnie jest dostępny w wielu przeglądarkach, a rozdzielczość jest ograniczona do 100 mikrosekund lub więcej. W przypadku izolacji między źródłami rozdzielczość może wynosić 5 mikrosekund lub więcej.
Funkcje, które będą dostępne w stanie izolowanym od zasobów z innych domen.

Stan izolacji od zasobów z innych domen uniemożliwia też modyfikowanie elementu document.domain. (Możliwość zmiany document.domain umożliwia komunikację między dokumentami z tej samej witryny i była uważana za lukę w zasadach dotyczących tej samej domeny).

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

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

Te nagłówki nakazują przeglądarce blokowanie wczytywania zasobów lub elementów iframe, które nie zostały włączone do wczytywania przez dokumenty z innych domen, i uniemożliwiają oknom z innych domen bezpośrednie interakcje z Twoim dokumentem. Oznacza to również, że zasoby wczytywane z innych domen wymagają zgody użytkownika.

Aby sprawdzić, czy strona internetowa jest w stanie izolacji od zasobów z innych domen, zbadaj self.crossOriginIsolated.

Z tego artykułu dowiesz się, jak korzystać z tych nowych nagłówków. W kolejnym artykule podam więcej informacji i kontekstu.

Wdrażanie COOP i COEP w celu izolowania witryny od innych domen

Integracja COOP i COEP

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

Gdy w dokumencie najwyższego poziomu włączysz COOP: same-origin, okna z tej samej domeny i okna otwarte z tego dokumentu będą miały osobną grupę kontekstu przeglądania, chyba że znajdują się w tej samej domenie z tym samym ustawieniem COOP. W ten sposób wymuszana jest izolacja otwartych okien, a wzajemna komunikacja między nimi jest wyłączona.

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

Grupa kontekstów przeglądania

Możesz sprawdzić, czy otwierające okno i otwierane okno znajdują się w osobnych grupach kontekstów przeglądania, korzystając z Narzędzi deweloperskich.

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

Upewnij się, że wszystkie zasoby na stronie są wczytywane z nagłówkami HTTP CORP lub CORS. Ten krok jest wymagany w kroku 4, czyli włączaniu COEP.

W zależności od charakteru zasobu musisz wykonać te 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 innego źródła, ustaw nagłówek Cross-Origin-Resource-Policy: same-site.
  • Jeśli zasób jest ładowany z kontrolowanych przez Ciebie źródeł, w miarę możliwości ustaw nagłówek Cross-Origin-Resource-Policy: cross-origin.
  • W przypadku zasobów z innych domen, nad którymi nie masz kontroli:
    • Użyj atrybutu crossorigin w tagu HTML wczytywania, jeśli zasób jest udostępniany z CORS. (na przykład <img src="***" crossorigin>).
    • Poproś właściciela zasobu o obsługę CORS lub CORP.
  • W przypadku tagów iframe postępuj zgodnie z powyższymi zasadami i ustaw wartość Cross-Origin-Resource-Policy: cross-origin (lub same-site, same-origin w zależności od kontekstu).
  • Skrypty ładowane za pomocą tagu WebWorker muszą być obsługiwane z tego samego źródła, więc nie potrzebujesz nagłówków CORP ani CORS.
  • W przypadku dokumentu lub procesu roboczego obsługiwanego za pomocą COEP: require-corp podzasoby z innej domeny wczytywane bez CORS muszą ustawić nagłówek Cross-Origin-Resource-Policy: cross-origin, aby można było je osadzić. Dotyczy to na przykład tych usług: <script>, importScripts, <link>, <video>, <iframe> itp.

3. Ocena zasobów osadzonych za pomocą nagłówka HTTP COEP Report-Only

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

Zastosuj to rekursywnie do wszystkich dokumentów, w tym dokumentu najwyższego poziomu, elementów iframe i skryptów roboczych. Więcej informacji o nagłówku HTTP Report-Only znajdziesz w artykule Obserwowanie problemów za pomocą interfejsu Reporting API.

4. Włączanie COEP

Gdy potwierdzisz, że wszystko działa i wszystkie zasoby można wczytać, zmień nagłówek Cross-Origin-Embedder-Policy-Report-Only na nagłówek Cross-Origin-Embedder-Policy o tej samej wartości we wszystkich dokumentach, w tym w dokumentach osadzonych za pomocą elementów iframe i skryptów roboczych.

Sprawdź, 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 tej samej grupie kontekstów przeglądania. Za pomocą tego interfejsu API możesz sprawdzić, czy udało Ci się odizolować grupę kontekstów przeglądania i uzyskać dostęp do zaawansowanych funkcji, takich jak performance.measureUserAgentSpecificMemory().

Rozwiązywanie problemów za pomocą Narzędzi deweloperskich w Chrome

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

Problemy z COEP w kolumnie Stan w panelu Sieć.

Następnie możesz 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 okien wyskakujących możesz też sprawdzić w panelu Aplikacja. Po lewej stronie otwórz sekcję „Ramki” i rozwiń „Góra”, aby zobaczyć strukturę zasobu.

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

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

Możesz też sprawdzić stan wyskakujących okien, np. czy są one odizolowane od innych domen.

Inspektor wyskakującego okna Narzędzi 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 Reporting API, aby przeglądarka użytkownika wysyłała raport, gdy COEP blokuje wczytywanie zasobu lub COOP izoluje okno wyskakujące. Chrome obsługuje interfejs Reporting API od wersji 69 w różnych zastosowaniach, w tym w przypadku COEP i COOP.

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

Przykładowy raport COEP

Przykładowy ładunek raportu COEP w przypadku zablokowania zasobu z innej domeny 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ładowy ładunek raportu COOP, gdy otwarte jest odizolowane wyskakujące okienko:

[{
  "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 kontekstów przeglądania próbują uzyskać do siebie dostęp (tylko w trybie „report-only”), COOP również wysyła raport. Na przykład raport w przypadku próby wykonania działania postMessage() 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 włączyć stronę internetową w specjalny stan izolacji od innych domen. Możesz sprawdzić, czy strona internetowa jest w stanie izolacji z innych domen.self.crossOriginIsolated

Będziemy aktualizować ten post w miarę udostępniania nowych funkcji w tym stanie izolacji między źródłami i wprowadzania dalszych ulepszeń w narzędziach deweloperskich w zakresie COOP i COEP.

Zasoby