Chrome 将禁止修改 document.domain 以放宽同源政策

如果您的网站依赖于 document.domain 设置,则您必须采取行动。

更新

  • 2023 年 5 月 30 日:我们已宣布document.domain Setter 将于 Chrome 115 中弃用。
  • 2023 年 4 月 7 日:在 Chrome 112 中发布此更改之前,我们发现了一个问题。默认情况下要移除的 document.domain Setter 目前已暂停,新的发布里程碑尚未确定。请不时查看这篇博文,或订阅 blink-dev此会话
  • 2023 年 1 月 20 日:更新时间表 - 从 Chrome 112 开始,系统将默认移除 document.domain 设置器。此外,还添加了关于企业政策的提及,以控制 document.domain 行为。
  • 2022 年 7 月 25 日:更新了时间表 - 从 Chrome 109 开始,系统将默认移除 document.domain Setter。
  • 2022 年 2 月 4 日:更新了新时间表 - 从 Chrome 100 开始,我们会在“问题”面板中显示警告;从 Chrome 106 开始,默认移除 document.domain Setter。

document.domain 旨在获取或设置来源的主机名。

在 Chrome 中,网站将无法设置 document.domain。您需要使用其他方法(例如 postMessage() 或 Channel Messaging API)进行跨源通信。我们计划在 Chrome 112 中尽早发布此更改,但具体取决于对发布意向的回复。

如果您的网站依赖于通过 document.domain 放宽同源政策才能正常运行,则该网站以及所有其他需要此行为的其他文档都需要发送 Origin-Agent-Cluster: ?0 标头(请注意,如果只有一个文档设置了 document.domain,则 document.domain 没有任何效果)。

为什么要将 document.domain 设为不可变?

许多网站会设置 document.domain,以允许同网站但跨源网页之间进行通信。

具体使用方法如下:

假设 https://parent.example.com 上的某个网页嵌入了 https://video.example.com 中的 iframe 页面。这些网页具有相同的 eTLD+1 (example.com),但子网域不同。如果两个网页的 document.domain 都设置为 'example.com',则浏览器会将这两个来源视为同源。

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 存在安全问题,因此规范已发生变化,提醒用户避免使用 document.domain目前与其他浏览器供应商的讨论也朝着这个方向发展。

例如,当两个网页设置 document.domain 时,它们可以假装自己是同源的。如果这些网页使用的是具有不同子网域的共享托管服务,这一点尤为重要。设置 document.domain 会开放对同一服务托管的所有其他网站的访问权限,这会让攻击者更容易访问您的网站。之所以能这么做,是因为 document.domain 会忽略域名的端口号部分。

如需详细了解设置 document.domain 的安全影响,请参阅 MDN 上的“Document.domain”页面

Chrome 计划在 Chrome 112 中将 document.domain 设为不可变。

如何判断我的网站是否受到影响?

如果您的网站受到此变更的影响,Chrome 会在 DevTools 的“问题”面板中发出警告。请注意右上角的黄色标志。

修改 document.domain 后,问题面板中会显示一条警告。
修改 document.domain 后,问题面板中会显示一条警告。

如果您设置了报告端点,系统还会向您发送弃用报告。详细了解如何将 Reporting API 与现有报告收集服务搭配使用,或通过构建自己的内部解决方案来使用该 API。

您可以通过 Lighthouse 已废弃的 API 审核对您的网站进行运行,以查找计划从 Chrome 中移除的所有 API。

其他跨源通信

目前,您有三种方法可以为您的网站替换 document.domain

使用 postMessage() 或 Channel Messaging API

在大多数用例中,跨源 postMessage()Channel Messaging API 可以替代 document.domain

在以下示例中:

  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 默认变为不可变,文档仍可继续设置 document.domain

为企业政策配置 OriginAgentClusterDefaultEnabled

管理员可以选择将 OriginAgentClusterDefaultEnabled 政策配置为 false,以便在组织中的所有 Chrome 实例上默认设置 document.domain。如需了解详情,请参阅 Chrome 企业版政策列表和管理功能 | 文档

浏览器兼容性

资源

致谢

照片由 Braydon Anderson 拍摄,选自 Unsplash