使用 Origin-Agent-Cluster 标头请求性能隔离

新增了 HTTP 响应标头,可限制全网域脚本攻击,并向浏览器请求专用资源。

多梅尼克·丹尼科拉
Domenic Denicola

Origin-Agent-Cluster 是一个新的 HTTP 响应标头,用于指示浏览器阻止同网站跨源网页之间的同步脚本访问。浏览器还可以使用 Origin-Agent-Cluster 作为提示,指出您的源应获取自己的独立资源(例如专用进程)。

浏览器兼容性

目前,Origin-Agent-Cluster 头文件仅在 Chrome 88 及更高版本中实现。此测试是在与 Mozilla Firefox 代表密切协作而设计的,这些代表已将其标记为值得进行原型设计,并得到了 Safari 所用的浏览器引擎 WebKit 代表的初步正面认可

但与此同时,您可以放心地为所有用户部署 Origin-Agent-Cluster 标头。无法理解该文件的浏览器只会忽略它。此外,由于以源为键的代理集群中的页面实际上可以执行比以网站为键的代理集群少一些的操作(默认),因此无需担心互操作性问题。

为什么浏览器无法自动隔离同网站源

Web 是基于同源政策构建的,同源政策是一项安全功能,限制文档和脚本与其他来源的资源交互方式。例如,托管在 https://a.example 的网页与 https://b.examplehttps://sub.a.example 上的网页不同。

在后台,浏览器以不同的方式使用源站分离。过去,即使不同的源站无法访问彼此的数据,它们仍然会共享操作系统线程、进程和内存分配等资源。这意味着,如果某个标签页的运行速度变慢,所有其他标签页的速度都会变慢。或者,如果某个标签页占用的内存过多,会导致整个浏览器崩溃。

如今,浏览器更为先进,会尝试将不同的来源拆分到不同的进程中。具体运作方式因浏览器而异:大多数浏览器标签页之间有一定程度的分隔,但单个标签页中的不同 iframe 可能会共享一个进程。此外,由于进程会产生一些内存开销,因此它们使用启发法来避免生成过多进程:例如,Firefox 具有可由用户配置的进程限制,Chrome 会在桌面设备(内存较多)和移动设备(内存不足)之间改变其行为。

这些启发词语并不完美。它们存在一个重要限制:由于同源政策存在允许 https://sub.a.examplehttps://a.example 等子网域相互通信的例外情况,因此浏览器无法自动隔离彼此。

此默认行为称为“以网站为键的代理集群”,也就是说,浏览器会根据其网站对网页进行分组。新的 Origin-Agent-Cluster 标头要求浏览器更改给定页面的这一默认行为,将给定页面放入以源为键的代理集群中,使其仅与来源完全相同的其他页面进行分组。具体而言,同网站跨源页面将从代理集群中排除。

通过这种选择性启用分离,浏览器可以为这些以源为键的新代理集群提供自己的专用资源,这些资源不会与其他源站的资源组合在一起。例如,此类页面可以有自己的进程,也可以被调度到单独的线程上。向网页添加 Origin-Agent-Cluster 标头,可向浏览器表明该网页可受益于此类专用资源。

不过,为了执行分离并获得这些好处,浏览器需要停用一些旧版功能。

以源为键的网页无法执行哪些操作

当您的网页位于以源为键的代理集群中时,您将无法与之前可用的同网站跨源网页进行通信。具体而言:

  • 您无法再设置 document.domain。这是一项旧版功能,通常允许同网站跨源页面同步访问彼此的 DOM,但在以源为键的代理集群中,此功能处于停用状态。

  • 您无法再通过 postMessage()WebAssembly.Module 对象发送到其他同网站跨源网页。

  • (仅限 Chrome)您无法再将 SharedArrayBufferWebAssembly.Memory 对象发送到其他同网站跨源网页。

何时使用以源为键的代理集群

Origin-Agent-Cluster 标头中受益最多的来源是:

  • 充分利用他们自己的专属资源,取得最佳成效。例如,性能密集型游戏、视频会议网站或多媒体创作应用。

  • 包含来源不同但同一网站的资源密集型 iframe。例如,如果 https://mail.example.com 嵌入了 https://chat.example.com iframe,源键 https://mail.example.com/ 可确保聊天团队编写的代码不会意外干扰邮件团队编写的代码,并且可以提示浏览器为其提供单独的进程,以便单独调度它们,并降低它们对性能的影响。

  • 期望嵌入到不同来源的同网站网页中,但知道自己要占用大量资源。例如,如果 https://customerservicewidget.example.com 预计会使用大量资源进行视频聊天,并且将在整个 https://*.example.com 中的各个源中嵌入,则维护该 widget 的团队可以使用 Origin-Agent-Cluster 标头来尝试降低其对嵌入器的性能影响。

此外,您还需要确保您可以停用上述很少使用的跨源通信功能,并且您的网站使用 HTTPS

但归根结底,这些只是指南。以源为键的代理集群对您的网站是否有帮助最终通过测量来确定。具体而言,您需要衡量网页指标,或许还需要衡量内存用量,以了解使用源键设置的影响。(内存用量尤其是一个潜在的担忧,因为增加正在执行的进程数量可能会导致每个进程的内存开销增加。)您不应该只是推出源键操作并寄希望于最好的结果。

这与跨域隔离有何关系?

通过 Origin-Agent-Cluster 标头实现的代理集群的源键与通过 Cross-Origin-Opener-PolicyCross-Origin-Embedder-Policy 标头的跨域隔离相关但彼此独立。

任何将自己设为跨域隔离的网站也会停用与使用 Origin-Agent-Cluster 标头时相同的同网站跨源通信功能。不过,在跨域隔离的基础上,Origin-Agent-Cluster 标头仍然很有用,作为给浏览器修改其资源分配启发式方法的附加提示。因此,您仍应考虑应用 Origin-Agent-Cluster 标头并衡量结果,即使在已经跨域隔离的页面上也是如此。

如何使用 Origin-Agent-Cluster 标头

如需使用 Origin-Agent-Cluster 标头,请将您的 Web 服务器配置为发送以下 HTTP 响应标头:

Origin-Agent-Cluster: ?1

?1 的值是布尔值 true 值的结构化标头语法。

请务必针对来自您的来源的所有响应(而不仅仅是某些网页)发送此标头。否则,结果可能会不一致,在这种情况下,浏览器会“记住”看见了一个源键请求,因此即使在未请求源键的网页上,浏览器也会“记住”源键。反之,如果用户访问的第一个页面没有该标头,浏览器就会记住您的来源不希望以源为键,并在后续页面上忽略该标头。

为什么浏览器不能始终遵从标题?

创建此“内存”的目的是确保源的键控一致性。如果源站中的某些页面以源键为键,而其他页面不是以源键为键,那么您可能会有两个同源页面,它们被放入不同的代理集群中,因此不允许相互通信。对 Web 开发者和浏览器的内部而言,这是非常奇怪的。因此,如果标头与之前从给定来源看到的内容不一致,则 Origin-Agent-Cluster 的规范会忽略该标头。在 Chrome 中,这会导致控制台警告。

这种一致性的范围限定为浏览上下文组,即一组标签页、窗口或 iframe,它们都可以通过 window.openerframes[0]window.parent 等机制相互访问。这意味着,当某个源站的源键或网站键设置确定后(浏览器看到或看不到标头),更改该标头需要打开一个全新的标签页,而不能以任何方式连接到旧标签页。

这些详细信息对于测试 Origin-Agent-Cluster 标头非常重要。首次将标签页添加到网站时,您无法仅重新加载页面;您需要关闭标签页并打开一个标签页。

如需检查是否应用了 Origin-Agent-Cluster 标头,请使用 JavaScript window.originAgentCluster 属性。如果标头(或其他机制,例如跨域隔离)导致源键生成,则此值为 true;如果未实现 Origin-Agent-Cluster 标头,此值为 false;如果浏览器未实现 Origin-Agent-Cluster 标头,此值为 undefined。 通过将这些数据记录到分析平台,您可以检查服务器配置是否正确无误。

最后请注意,Origin-Agent-Cluster 标头仅适用于安全上下文,即 HTTPS 网页或 http://localhost。非 localhost HTTP 页面支持以源为键的代理集群。

源键不是安全功能

虽然使用以源为键的代理集群可以将源与同网站跨源页面的同步访问隔离开来,但它无法提供安全相关标头(如 Cross-Origin-Resource-PolicyCross-Origin-Opener-Policy)的保护。特别是,它不是针对 Spectre 等边信道攻击的可靠防护措施。

这可能有点意外,因为源键有时会导致源站获得自己的进程,而单独的进程是防范旁路攻击的重要防御。但请注意,Origin-Agent-Cluster 标头只是这方面的提示。浏览器没有义务为来源提供单独的进程,也可能会因各种原因而这样做:

  • 浏览器可能未实施该技术来执行此操作。例如,Safari 和 Firefox 目前可以将单独的标签页放入各自的进程中,但无法针对 iframe 执行此操作。

  • 浏览器可能会判定不值得在单独进程中开销。例如,在低内存 Android 设备或 Android WebView 中,Chrome 使用的进程会尽可能少。

  • 浏览器可能希望遵循 Origin-Agent-Cluster 标头指示的请求,但为实现这一目的,浏览器可以使用与进程不同的隔离技术。例如,Chrome 正在探索使用线程而非进程来实现此类性能隔离。

  • 用户或在其他网站上运行的代码可能已经导航到您的源站上以网站为键的网页,导致一致性保证生效,并完全忽略 Origin-Agent-Cluster 标头。

出于这些原因,切记不要将以源为键的代理集群视为安全功能。相反,它是一种帮助浏览器确定资源分配优先级的方式,它会提示源站将从专用资源中受益(并且您愿意放弃某些功能作为交换)。

反馈

如果您正在使用或考虑使用 Origin-Agent-Cluster 标头,Chrome 团队非常期待收到您的宝贵意见。您的公众利益和支持有助于我们确定相关功能的优先顺序,并向其他浏览器供应商展示其重要性。向 @ChromiumDev 发推文,告诉 Chrome DevRel 您的想法和体验。

如果您对该规范或该功能的工作原理详情还有其他疑问,可以在 HTML 标准 GitHub 代码库中提交问题。如果您遇到 Chrome 实现方面的任何问题,可以在 new.crbug.com 上提交 bug,并将“组件”字段设为 Internals>Sandbox>SiteIsolation

了解详情

如需详细了解以源为键的代理集群,请访问以下链接了解详情: