COOP と COEP を使用してウェブサイトを「クロスオリジン分離」を実現

COOP と COEP を使用してクロスオリジン分離環境を設定し、SharedArrayBufferperformance.measureUserAgentSpecificMemory()、高解像度タイマーなどの強力な機能を有効にして精度を高めます。

更新

  • 2022 年 6 月 21 日: クロスオリジン分離が有効になっている場合は、ワーカー スクリプトにも注意が必要です。説明を追加しました。
  • 2021 年 8 月 5 日: JS Self-Profiling API は、クロスオリジン分離を必要とする API の一つとして記載されていましたが、最近の方向性の変更を反映して削除されました。
  • 2021 年 5 月 6 日: 報告されたフィードバックと問題に基づき、クロスオリジン分離されていないサイトでの SharedArrayBuffer の使用を Chrome M92 で制限するタイムラインを調整することにしました。
  • 2021 年 4 月 16 日: 新しい COEP 認証情報なしモードと、クロスオリジン分離の緩和条件としての COOP same-origin-allow-popups に関する注記を追加しました。
  • 2021 年 3 月 5 日: SharedArrayBufferperformance.measureUserAgentSpecificMemory()、デバッグ機能の制限を削除し、Chrome 89 で完全に有効になりました。精度が向上する今後の機能である performance.now()performance.timeOrigin が追加されました。
  • 2021 年 2 月 19 日: 機能ポリシー allow="cross-origin-isolated" と DevTools のデバッグ機能に関する注記を追加しました。
  • 2020 年 10 月 15 日: self.crossOriginIsolated は Chrome 87 以降で利用できます。これを反映して、self.crossOriginIsolatedtrue を返す場合、document.domain は不変です。performance.measureUserAgentSpecificMemory() のオリジン トライアルは終了し、Chrome 89 ではデフォルトで有効になっています。Android Chrome の共有配列バッファは、Chrome 88 以降で利用可能になります。

一部のウェブ API は、Spectre などのサイドチャネル攻撃のリスクを高めます。このリスクを軽減するために、ブラウザにはクロスオリジン分離と呼ばれるオプトインベースの分離環境が用意されています。クロスオリジンの分離状態を使用すると、ウェブページは次のような特権機能を使用できるようになります。

API 説明
SharedArrayBuffer WebAssembly スレッドに必要です。この機能は Android 版 Chrome 88 以降で利用できます。パソコン版は現在、 サイト分離によってデフォルトで有効になっていますが、クロスオリジン分離状態が必要であり、 Chrome 92 ではデフォルトで無効になります
performance.measureUserAgentSpecificMemory() Chrome 89 以降で利用可能。
performance.now()performance.timeOrigin 現在、多くのブラウザで利用可能で、解像度は 100 マイクロ秒以上に制限されています。クロスオリジン分離では、解像度は 5 マイクロ秒以上にすることができます。
クロスオリジン分離状態の背後で利用できる機能。

クロスオリジン分離状態は、document.domain の変更も防止します。(document.domain を変更できると、同一サイトのドキュメント間の通信が可能になり、同一オリジン ポリシーの抜け穴と見なされています)。

クロスオリジン分離状態を有効にするには、メイン ドキュメントで次の HTTP ヘッダーを送信する必要があります。

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

これらのヘッダーは、クロスオリジン ドキュメントによる読み込みをオプトインしていないリソースや iframe の読み込みをブロックし、クロスオリジン ウィンドウがドキュメントと直接やり取りできないようにブラウザに指示します。また、クロスオリジンで読み込まれるリソースにはオプトインが必要になります。

ウェブページがクロスオリジン分離状態にあるかどうかは、self.crossOriginIsolated を調べることで判断できます。

この記事では、これらの新しいヘッダーの使用方法について説明します。フォローアップ記事では、背景とコンテキストについて詳しく説明します。

COOP と COEP をデプロイして、ウェブサイトをクロスオリジン分離する

COOP と COEP を統合する

1. 最上位ドキュメントに Cross-Origin-Opener-Policy: same-origin ヘッダーを設定する

トップレベル ドキュメントで COOP: same-origin を有効にすると、同じオリジンのウィンドウと、そのドキュメントから開いたウィンドウは、同じ COOP 設定の同じオリジンにない限り、個別のブラウジング コンテキスト グループになります。したがって、開いているウィンドウに対して分離が適用され、両方のウィンドウ間の相互通信が無効になります。

ブラウジング コンテキスト グループは、相互に参照できるウィンドウのセットです。たとえば、<iframe> を介して埋め込まれた最上位ドキュメントとその子ドキュメントなどです。ウェブサイト(https://a.example)がポップアップ ウィンドウ(https://b.example)を開くと、開いたウィンドウとポップアップ ウィンドウは同じブラウジング コンテキストを共有するため、window.opener などの DOM API を介して相互にアクセスできます。

ブラウジング コンテキスト グループ

ウィンドウを開いたユーザーとその開かれたユーザーが、DevTools で別々のブラウジング コンテキスト グループに属しているかどうかを確認できます。

2. リソースで CORP または CORS が有効になっていることを確認する

ページ内のすべてのリソースが CORP または CORS HTTP ヘッダーで読み込まれていることを確認します。このステップは、ステップ 4、COEP の有効化に必要です。

リソースの性質に応じて、次の手順を実施します。

  • リソースが同じ送信元からのみ読み込まれることが予想される場合は、Cross-Origin-Resource-Policy: same-origin ヘッダーを設定します。
  • リソースが同じサイトからのみ、異なるオリジンから読み込まれることが予想される場合は、Cross-Origin-Resource-Policy: same-site ヘッダーを設定します。
  • リソースが管理対象のクロスオリジンから読み込まれる場合は、可能であれば Cross-Origin-Resource-Policy: cross-origin ヘッダーを設定します。
  • 管理できないクロスオリジン リソースの場合:
    • リソースが CORS で提供される場合は、読み込み HTML タグで crossorigin 属性を使用します。(例: <img src="***" crossorigin>。)
    • リソースのオーナーに、CORS または CORP のサポートを依頼します。
  • iframe の場合は、上記と同じ原則に従って Cross-Origin-Resource-Policy: cross-origin(またはコンテキストに応じて same-sitesame-origin)を設定します。
  • WebWorker で読み込まれるスクリプトは同じオリジンから提供される必要があるため、CORP ヘッダーや CORS ヘッダーは必要ありません。
  • COEP: require-corp で提供されるドキュメントまたはワーカーの場合、CORS なしで読み込まれるクロスオリジン サブリソースは、埋め込みを有効にするために Cross-Origin-Resource-Policy: cross-origin ヘッダーを設定する必要があります。たとえば、<script>importScripts<link><video><iframe> などが該当します。

3. COEP レポート専用 HTTP ヘッダーを使用して埋め込みリソースを評価する

COEP を完全に有効にする前に、Cross-Origin-Embedder-Policy-Report-Only ヘッダーを使用してドライランを行い、ポリシーが実際に機能するかどうかを確認できます。埋め込みコンテンツをブロックすることなくレポートを受け取ることができます。

最上位ドキュメント、iframe、ワーカー スクリプトなど、すべてのドキュメントに再帰的に適用します。Report-Only HTTP ヘッダーの詳細については、Reporting API を使用して問題を検出するをご覧ください。

4. COEP を有効にする

すべてが機能し、すべてのリソースが正常に読み込まれることを確認したら、iframe やワーカー スクリプト経由で埋め込まれているドキュメントを含むすべてのドキュメントで、Cross-Origin-Embedder-Policy-Report-Only ヘッダーを Cross-Origin-Embedder-Policy ヘッダーに切り替え、同じ値を設定します。

self.crossOriginIsolated で分離が成功したかどうかを確認する

self.crossOriginIsolated プロパティは、ウェブページがクロスオリジン分離状態にあり、すべてのリソースとウィンドウが同じブラウジング コンテキスト グループ内で分離されている場合に true を返します。この API を使用すると、ブラウジング コンテキスト グループが正常に分離され、performance.measureUserAgentSpecificMemory() などの強力な機能にアクセスできるようになったかどうかを確認できます。

Chrome DevTools を使用して問題をデバッグする

画像など、画面にレンダリングされるリソースの場合、リクエストがブロックされ、ページに画像がないことが示されるため、COEP の問題を検出するのは比較的簡単です。ただし、スクリプトやスタイルなど、視覚的な影響が必ずしもないリソースの場合、COEP の問題に気付かない可能性があります。このような場合は、DevTools の [Network] パネルを使用します。COEP に問題がある場合は、[ステータス] 列に (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) と表示されます。

[ネットワーク] パネルの [ステータス] 列に COEP の問題が表示される。

エントリをクリックすると、詳細が表示されます。

COEP の問題の詳細は、[ネットワーク] パネルでネットワーク リソースをクリックすると、[ヘッダー] タブに表示されます。

iframe とポップアップ ウィンドウのステータスは、[アプリケーション] パネルで確認することもできます。左側の [フレーム] セクションに移動し、[上] を開いてリソース構造の詳細を確認します。

SharedArrayBuffer の可用性など、iframe のステータスを確認できます。

Chrome DevTools の iframe インスペクタ

ポップアップ ウィンドウのステータス(クロスオリジン分離かどうかなど)を確認することもできます。

Chrome DevTools ポップアップ ウィンドウ インスペクタ

Reporting API を使用して問題をモニタリングする

Reporting API は、さまざまな問題を検出できる別のメカニズムです。Reporting API を構成して、COEP がリソースの読み込みをブロックしたときや、COOP がポップアップ ウィンドウを分離したときに、ユーザーのブラウザにレポートを送信するよう指示できます。Chrome では、バージョン 69 以降、COEP や COOP などさまざまな用途で Reporting API をサポートしています。

Reporting API を構成してレポートを受信するサーバーをセットアップする方法については、Reporting API の使用をご覧ください。

COEP レポートの例

クロスオリジン リソースがブロックされた場合の COEP レポート ペイロードの例を次に示します。

[{
  "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"
}]

COOP レポートの例

ポップアップ ウィンドウが分離状態で開かれた場合の COOP レポート ペイロードの例は次のとおりです。

[{
  "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"
}]

異なるブラウジング コンテキスト グループが相互にアクセスしようとすると(「レポートのみ」モードの場合のみ)、COOP もレポートを送信します。たとえば、postMessage() が試行されたときのレポートは次のようになります。

[{
  "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"
}]

まとめ

COOP と COEP の HTTP ヘッダーを組み合わせて、ウェブページを特別なクロスオリジン分離状態にします。self.crossOriginIsolated を調べて、ウェブページがクロスオリジン分離状態にあるかどうかを確認できます。

この投稿は、このクロスオリジン分離状態に新しい機能が利用可能になり、COOP と COEP に関する DevTools がさらに改善されるにつれて更新されます。

リソース