ウェブサイトが document.domain の設定に依存している場合は、対応が必要です。
変更点とその理由
Chrome 115 以降、ウェブサイトは document.domain を設定できなくなります。document.domain は変更不可になります。クロスオリジン通信を行うには、postMessage() や Channel Messaging API などの代替方法を使用する必要があります。
この変更は段階的にロールアウトされます。
他のブラウザでも、この機能は最終的に非推奨になり、削除される予定です。詳しくは、ブラウザの互換性のセクションをご覧ください。
document.domain を不変にする理由
document.domain は、送信元のホスト名を取得または設定するように設計されています。多くのウェブサイトでは、同一サイトのクロスオリジンページ間の通信を許可するように document.domain を設定しています。
これは便利な手法ですが、同一オリジン ポリシーを緩和するため、セキュリティ リスクが生じます。document.domain に関するセキュリティ上の懸念から、仕様が変更され、使用しないようユーザーに警告しています。
詳細: document.domain を不変にする理由
document.domain の現在の使用方法
多くのウェブサイトでは、同一サイトのクロスオリジンページ間の通信を許可するために document.domain を設定しています。
同じサイトでもクロスオリジンのサイトは、eTLD+1 は同じでもサブドメインが異なります。
これまでの document.domain の使用方法は次のとおりです。
https://parent.example.com のページに https://video.example.com の iframe ページが埋め込まれているとします。これらのページは、同じ eTLD+1(example.com)で、サブドメインが異なります。両方のページの document.domain が 'example.com' に設定されている場合、ブラウザは 2 つのオリジンを同じオリジンとして扱います。
https://parent.example.com の document.domain を設定します。
// Confirm the current origin of "parent.example.com"
console.log(document.domain);
// Set the document.domain
document.domain = 'example.com';
console.log(document.domain);
https://video.example.com の document.domain を設定します。
// Confirm the current origin of "video.example.com"
console.log(document.domain);
// Set the document.domain
document.domain = 'example.com';
console.log(document.domain);
https://parent.example.com に対して https://video.example.com のクロスオリジン DOM 操作を作成できるようになりました。
ウェブサイトは、同じサイトのドキュメントがより簡単に通信できるように document.domain を設定します。この変更により同一オリジン ポリシーが緩和されるため、親ページは iframe のドキュメントにアクセスして DOM ツリーを走査できるようになります。その逆も同様です。
これは便利な手法ですが、セキュリティ リスクが生じます。
document.domain のセキュリティに関する懸念
document.domain に関するセキュリティ上の懸念から、その使用を避けるようユーザーに警告する仕様が変更されました。
たとえば、2 つのページが document.domain を設定すると、同じオリジンであるかのように見せかけることができます。これは、これらのページが異なるサブドメインを持つ共有ホスティング サービスを使用する場合に特に重要です。document.domain を設定すると、同じサービスでホストされている他のすべてのサイトにアクセスできるようになります。これにより、攻撃者がサイトに簡単にアクセスできるようになります。これは、document.domain がドメインのポート番号部分を無視するためです。
document.domain の設定によるセキュリティ上の影響の詳細については、MDN の「Document.domain」ページをご覧ください。
ブラウザの互換性
- HTML 仕様では、この機能は削除する必要があることが明記されています。
- Mozilla は、デフォルトで document.domainを無効にすることをプロトタイプ化する価値があると考えています。
- WebKit は、document.domainセッターのデプリケーションに比較的前向きであると示しています。
- 他のブラウザ ベンダーとの協議
- WHATWG / HTML ワーキング グループのプル リクエスト(試験運用中の機能)
サイトが影響を受けているかどうかを確認するにはどうすればよいですか?
ウェブサイトがこの変更の影響を受ける場合は、Chrome の DevTools の [Issues] パネルに警告が表示されます。この警告は 2022 年に追加されました。DevTools の右上に黄色のフラグが表示されます。
LightHouse の非推奨 API 監査でサイトを実行して、Chrome から削除される予定のすべての API を確認することもできます。
Reporting API を設定している場合は、このサポート終了について通知する非推奨レポートが Chrome から送信されています。既存のレポート収集サービスを使用するか、独自の社内ソリューションを構築して Reporting API を使用する方法について学びます。
この変更の実装例を確認するにはどうすればよいですか?
この変更は、Chrome 115 から段階的に展開されます。Chrome ブラウザにまだロールアウトされていない場合でも、この変更を有効にするには、次の手順を行います。
- chrome://flags/#origin-agent-cluster-defaultを開きます。
- [有効にする] を選択します。
- Chrome を再起動します。
代替手段はありますか?
最善の方法は、ページと構成要素のフレームをすべて同じオリジンでホストするなど、document.domain をまったく変更しないことです。これは、すべてのブラウザのすべてのバージョンで機能します。ただし、これを行うにはアプリを大幅に変更する必要があるため、引き続きクロスオリジン アクセスをサポートする代替手段も検討することをおすすめします。
document.domain の代わりに postMessage() または Channel Messaging API を使用する
ほとんどのユースケースでは、クロスオリジンの postMessage() または Channel Messaging API で document.domain を置き換えることができます。
下記の例で、
- https://parent.example.comは iframe 内の- https://video.example.comをリクエストし、- postMessage()を介してメッセージを送信して DOM を操作します。
- https://video.example.comは、メッセージを受信するとすぐに DOM を操作し、成功を親に通知します。
- https://parent.example.comは成功を通知します。
https://parent.example.com:
// Send a message to https://video.example.com
iframe.postMessage('Request DOM manipulation', 'https://video.example.com');
// Receive messages
iframe.addEventListener('message', (event) => {
  // Reject all messages except ones from https://video.example.com
  if (event.origin !== 'https://video.example.com') return;
  // Filter success messages
  if (event.data === 'succeeded') {
    // DOM manipulation is succeeded
  }
});
https://video.example.com:
// Receive messages
window.addEventListener('message', (event) => {
  // Reject all messages except ones from https://parent.example.com
  if (event.origin !== 'https://parent.example.com') return;
  // Do a DOM manipulation on https://video.example.com.
  // Send a success message to https://parent.example.com
  event.source.postMessage('succeeded', event.origin);
});
ぜひお試しください。postMessage() または Channel Messaging API では対応できない特定の要件がある場合は、Twitter の @ChromiumDev でお問い合わせいただくか、Stack Overflow で document.domain タグを使用してお問い合わせください。
最後の手段として、Origin-Agent-Cluster: ?0 ヘッダーを送信する
document.domain の設定を継続する正当な理由がある場合は、ターゲット ドキュメントとともに Origin-Agent-Cluster: ?0 レスポンス ヘッダーを送信できます。
Origin-Agent-Cluster: ?0
Origin-Agent-Cluster ヘッダーは、ドキュメントをオリジンキー エージェント クラスタで処理するかどうかをブラウザに指示します。Origin-Agent-Cluster の詳細については、Origin-Agent-Cluster ヘッダーを使用してパフォーマンス分離をリクエストするをご覧ください。
このヘッダーを送信すると、ドキュメントはデフォルトで変更不可になった後も document.domain を設定し続けることができます。
同じ動作を必要とする他のすべてのドキュメントも Origin-Agent-Cluster を送信する必要があります(document.domain を設定しているドキュメントが 1 つしかない場合、効果はありません)。
企業向けポリシーの OriginAgentClusterDefaultEnabled を構成する
必要に応じて、管理者は OriginAgentClusterDefaultEnabled ポリシーを false に構成して、組織全体の Chrome インスタンスで document.domain をデフォルトで設定できるようにします。詳しくは、Chrome Enterprise のポリシーリストと管理 | ドキュメントをご覧ください。
リソース
- Document.domain- Web API | MDN
- オリジンの分離と document.domainの非推奨
- document.domainの非推奨。· 問題 #564 · w3ctag/design-reviews
謝辞
写真: Finan Akbar(Unsplash)