Wasm モジュールの共有を同一オリジンに制限する

同じサイトの環境間での WebAssembly モジュールの共有は、同じオリジンにのみ制限されます。

エージェント クラスタを長期的にオリジンにスコープできるように、同じサイトだがクロスオリジンの環境間で WebAssembly(Wasm)モジュールを共有することは非推奨になります。このような方法で Wasm モジュールを使用しているデベロッパーは、Chrome 95 以降も引き続き使用できるように、同一オリジンでこれらのモジュールをインスタンス化する必要があります。

Wasm モジュールとは何か、その仕組み

WebAssembly プログラムは、デプロイ、読み込み、コンパイルの単位であるモジュールに編成されます。

次のサンプルコードでは、https://iframe.site.example からインポートされた Wasm モジュールが postMessage() を介して https://main.site.example と共有されています。これらのドメインは同一サイトですが、クロスオリジンです。

https://iframe.site.example の Wasm モジュール:

(async () => {
  const instance = await WebAssembly.instantiateStreaming(fetch('./add.wasm'), {});
  iframe.contentWindow.postMessage(instance.module, `https://main.site.example`);
})();

Chrome 95 以降、送信者と受信者は同一オリジンである必要があります。上記の例では、https://iframe.site.example を https://main.site.example にするか、その逆にする必要があります。

この操作が必要な理由

Chrome は、サイトキーのエージェント クラスタで、さまざまなドキュメント、タブ、フレームを内部的に処理しています。つまり、同じサイトのドキュメントは同じプロセス内で処理されます(具体的な仕組みはブラウザによって異なります)。最近、Chrome はより細かい単位(オリジン)で処理するようになりました。これをオリジンキー エージェント クラスタと呼びます。ただし、これを行うにはリソースが必要になるため、オリジンキー エージェント クラスタは、ヒューリスティックに限定されたウェブサイトにのみ適用されていました。

すべてのエージェント クラスタをデフォルトでオリジンキーにする予定です。これを実現するには、サイトキー付きオリジン クラスタを必要とする機能を制限する必要があります。

  • (Chrome のみ)SharedArrayBuffer オブジェクトまたは WebAssembly.Memory オブジェクトを他の同一サイトのクロスオリジン ページに送信できなくなりました。これは Chrome 92 以降ですでに導入されています。
  • postMessage() を介して他の同一サイトのクロスオリジン ページに WebAssembly.Module オブジェクトを送信できなくなりました。この変更については、以下で詳しく説明します。
  • document.domain を設定できなくなりました。これは、通常は同一サイトのクロスオリジン ページが互いの DOM に同期的にアクセスできるようにするレガシー機能ですが、オリジンキー エージェント クラスタでは無効になっています。

上記すべての変更に対応することで、Chrome はデフォルトでオリジンキーに基づくエージェントクラスタを使用するようになります。

オリジンキー エージェント クラスタの詳細については、Origin-Agent-Cluster ヘッダーを使用したパフォーマンス分離のリクエストをご覧ください。

次のステップとリソース

Chrome でオリジンキー エージェント クラスタをデフォルトで動作させるために、document.domain を読み取り専用にします。Chrome チームは、2022 年中にこの変更を導入することを目指しています。

写真撮影: Markus Winkler(出典: Unsplash)