同一オリジン ポリシーを緩和するために document.domain を変更できなくなります

ウェブサイトで document.domain の設定を使用している場合は、対応が必要です。

Eiji Kitamura
Eiji Kitamura

更新

  • 2023 年 5 月 30 日: Chrome 115 で document.domain セッターのサポート終了が適用されることを発表しました。
  • 2023 年 4 月 7 日: Chrome 112 でこの変更を公開する前に問題が特定されました。デフォルトで削除する document.domain セッターは現在停止されており、新しい配送マイルストーンはまだ決定されていません。このブログ投稿を再度確認するか、blink-devこちらのスレッドにご登録ください。
  • 2023 年 1 月 20 日: タイムラインの更新 - Chrome 112 以降、document.domain セッターはデフォルトで削除されます。また、document.domain の動作を制御するためのエンタープライズ ポリシーに関する記述も追加されています。
  • 2022 年 7 月 25 日: タイムラインの更新 - Chrome 109 以降、document.domain セッターはデフォルトで削除されます。
  • 2022 年 2 月 4 日: 新しいタイムラインを更新し、Chrome 100 以降では [問題] パネルに警告が表示され、Chrome 106 以降では document.domain セッターがデフォルトで削除されています。

document.domain は、オリジンのホスト名を取得または設定するように設計されています。

Chrome で、ウェブサイトで document.domain を設定できなくなります。クロスオリジンで通信するには、postMessage() や Channel Messaging API などの別の方法を使用する必要があります。Google では、この変更を早期にリリースする予定ですが、これはリリースの意向への回答次第です。

適切に動作させるために document.domain による同一オリジン ポリシーの緩和を利用しているウェブサイトでは、その動作を必要とする他のすべてのドキュメントと同様に、Origin-Agent-Cluster: ?0 ヘッダーを送信する必要があります(document.domain を 1 つのドキュメントでしか設定していない場合、効果はありません)。

document.domain を不変にする理由

多くのウェブサイトでは、同一サイトだクロスオリジンのページ間の通信を許可するために document.domain を設定しています。

使い方は次のとおりです。

https://parent.example.com のページに https://video.example.com の iframe ページを埋め込んでいるとします。これらのページは、異なるサブドメインを持つ同じ eTLD+1(example.com)を使用しています。両方のページの document.domain'example.com' に設定されている場合、ブラウザは 2 つのオリジンを同じオリジンとして扱います。

https://parent.example.comdocument.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.comdocument.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」ページをご覧ください。

Chrome 112 では document.domain を変更できなくなります。

サイトが影響を受けるかどうかを確認するにはどうすればよいですか?

ウェブサイトがこの変更の影響を受ける場合は、Chrome の DevTools の [Issues] パネルに警告が表示されます。右上に黄色い旗がついていることをご確認ください。

document.domain が変更されると、[問題] パネルに警告が表示されます。
document.domain が変更されると、[問題] パネルに警告が表示されます。

レポート エンドポイントを設定している場合は、サポート終了レポートも送信されます。詳しくは、既存のレポート収集サービス、または独自の自社ソリューションによる Reporting API の使用方法をご覧ください。

LightHouse の非推奨 API の監査を実施し、Chrome からの削除が予定されているすべての API を確認できます。

代替のクロスオリジン通信

現時点で、ウェブサイトの document.domain を置き換える方法は 3 つあります。

postMessage() または Channel Messaging API を使用します

ほとんどの場合、document.domain の代わりにクロスオリジンの postMessage() または Channel Messaging API を使用できます。

下記の例で、

  1. https://parent.example.com は iframe 内で https://video.example.com をリクエストし、postMessage() 経由でメッセージを送信して DOM を操作します。
  2. https://video.example.com はメッセージを受信するとすぐに DOM を操作し、成功を親に通知します。
  3. 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 の設定を続行できます。

エンタープライズ ポリシー向けに OriginAgentClusterDefaultEnabled を設定する

必要に応じて、管理者は OriginAgentClusterDefaultEnabled ポリシーを false に設定して、組織内の Chrome インスタンスで document.domain をデフォルトで設定できるようにします。詳しくは、Chrome Enterprise のポリシーリストと管理 | ドキュメントをご覧ください。

ブラウザの互換性

関連情報

謝辞

写真撮影: Braydon Anderson(出典: Unsplash