Android Chrome 88 和桌面版 Chrome 92 中的 SharedArrayBuffer 更新

可以肯定地说,SharedArrayBuffer 在网络上的经历略有起伏,但现在一切已稳定下来。以下是您有必要知道的信息:

简述

  • SharedArrayBuffer 目前在 Firefox 79 及更高版本中受支持,并将在 Android Chrome 88 中推出。不过,此功能仅适用于跨源隔离的网页。
  • SharedArrayBuffer 目前适用于桌面版 Chrome,但从 Chrome 92 开始,将仅限于跨源隔离网页。如果您认为无法及时进行此更改,可以注册源试用,以保留当前行为(至少要到 Chrome 113 为止)。
  • 如果您打算启用跨域隔离以继续使用 SharedArrayBuffer,请评估这会对您网站上的其他跨域元素(例如广告展示位置)产生的影响。查看您的任何第三方资源是否正在使用 SharedArrayBuffer,以了解相关影响和相关指导。

跨域隔离概览

您可以提供包含以下标头的网页,使该网页成为跨域隔离网页:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

执行此操作后,您的网页将无法加载跨源内容,除非相应资源通过 Cross-Origin-Resource-Policy 标头或 CORS 标头(Access-Control-Allow-* 等)明确允许加载跨源内容。

此外,还有一个报告 API,用于收集因 Cross-Origin-Embedder-PolicyCross-Origin-Opener-Policy 而失败的请求的相关数据。

如果您认为自己不能及时对 Chrome 92 做出这些更改,可以注册源试用,以便在至少等到 Chrome 113 之前保留当前的桌面版 Chrome 行为。

如需获取有关跨域隔离的更多指导和信息,请参阅本页底部的深入阅读部分。

我们是如何发展至今的呢?

SharedArrayBuffer 已包含在 Chrome 60 中(对于那些想用日期计算时间而不是 Chrome 版本的人来说,这是 2017 年 7 月),一切都很棒。为期 6 个月。

2018 年 1 月,我们在一些常用的 CPU 中发现了一个漏洞。如需了解完整详情,请参阅公告。这实际上意味着代码可以使用高分辨率计时器来读取不应访问的内存。

这对我们的浏览器供应商来说是一个问题,因为我们希望允许网站以 JavaScript 和 WASM 的形式执行代码,但要严格控制此代码可以访问的内存。进入我的网站后,我应该看不懂 您所打开的网上银行网站上的任何内容。事实上,我甚至不知道你是否开了网上银行网站。这些是 Web 安全的基础知识。

为了缓解此问题,我们降低了 performance.now() 等高分辨率计时器的分辨率。不过,您可以使用 SharedArrayBuffer 创建高分辨率计时器,方法是在工作器中的紧密循环中修改内存,然后在另一个线程中重新读取该内存。如果不对恶意代码造成严重影响,便无法有效缓解此问题,因此 SharedArrayBuffer 被完全停用。

常见的缓解措施是确保网页的系统进程不包含来自其他位置的敏感数据。Chrome 从一开始就投资了多进程架构(还记得漫画吗?),但在某些情况下,来自多个网站的数据可能最终会在同一个进程中:

<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->

这些 API 具有“旧版”行为,允许从其他来源选择使用的内容,而无需从其他来源选择启用。这些请求是使用另一个源的 Cookie 发出的,因此是一个完整的“已登录”请求。如今,新的 API 要求其他来源使用 CORS 选择启用。

为了解决了这些旧版 API 的问题,我们采取了如下措施:阻止内容在看似“不正确”时进入网页的进程,并将其命名为跨源读取屏蔽。因此,在上述情况下,我们不允许 JSON 进入该进程,因为它不是所有这些 API 的有效格式。也就是说,iframe 除外。对于 iframe 我们将内容放在不同的进程中

通过这些缓解措施,我们在 Chrome 68(2018 年 7 月)中重新引入了 SharedArrayBuffer,但仅适用于桌面设备。需要额外的流程,这意味着我们无法在移动设备上做到这一点。还有人指出,Chrome 的解决方案并不完整,因为我们只屏蔽了“不正确”的数据格式,而通过可猜测的网址的有效 CSS/JS/图片可能会包含私密数据(尽管这很不常见)。

网络标准人员聚集在一起,共同制定了更完整的跨浏览器解决方案。对应的解决方案是让网页可以这样表达:“本人有权在不选择启用其他来源的情况下,将其他来源内容纳入此进程”。此声明通过随网页提供的 COOP 和 COEP 标头完成。浏览器强制执行这一要求,作为交换,页面将获得对 SharedArrayBuffer 及其他具有类似功能的 API 的访问权限。其他来源可以通过 Cross-Origin-Resource-PolicyCORS 选择启用内容嵌入。

Firefox 是率先在版本 79(2020 年 7 月)中包含此限制的 SharedArrayBuffer

然后,在 2021 年 1 月,我写了这篇文章,你又读了它。你好。

这就是我们目前的情况。对于跨域隔离的网页,Chrome 88 使 SharedArrayBuffer 回到 Android,而 Chrome 92 则对桌面平台具有相同的要求,这不仅是为了保持一致性,也是为了实现完全跨域隔离。

延迟对桌面版 Chrome 的更改

这是一种“源试用”形式的临时异常,可让相关人员有更多时间来实现跨源隔离页面。它可以启用 SharedArrayBuffer,而无需对网页进行跨源隔离。该异常将在 Chrome 113 中到期,并且该例外情况仅适用于桌面版 Chrome。

  1. 为您的源请求令牌
  2. 将令牌添加到您的网页中。您可以采用下列两种方法:
    • 在每个网页的标头部分添加 origin-trial <meta> 标记。例如,可能如下所示:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • 如果您可以配置自己的服务器,则还可以使用 Origin-Trial HTTP 标头添加令牌。生成的响应标头应如下所示:
      Origin-Trial: TOKEN_GOES_HERE

深入阅读

横幅照片,由 Daniel GregoireUnsplash 用户发布