ウェブサイトが document.domain の設定に依存している場合は、対応が必要です。
変更点とその理由
Chrome 115 以降、ウェブサイトは document.domain
を設定できなくなります。Chrome では 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://video.example.com
に対して https://parent.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)