ウェブサイトが 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 ワーキング グループ pull リクエスト(テスト エクスペリエンスは保留中)
サイトが影響を受けるかどうかを確認するにはどうすればよいですか?
ウェブサイトがこの変更の影響を受ける場合は、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 を使用します
ほとんどの場合、document.domain
の代わりにクロスオリジンの postMessage()
または Channel Messaging API を使用できます。
下記の例で、
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
を送信する必要があります(1 つのドキュメントでしか設定していない場合、document.domain
の効果はありません)。
エンタープライズ ポリシー向けに OriginAgentClusterDefaultEnabled
を設定する
必要に応じて、管理者は OriginAgentClusterDefaultEnabled
ポリシーを false
に設定して、組織内の Chrome インスタンスで document.domain
をデフォルトで設定できるようにします。詳しくは、Chrome Enterprise のポリシーリストと管理 | ドキュメントをご覧ください。
関連情報
Document.domain
- ウェブ API | MDN- オリジンの分離と
document.domain
のサポート終了 document.domain
のサポートを終了します。· 問題 #564 · w3ctag/design-reviews
謝辞
写真撮影: Finan Akbar(Unsplash)