存储分区

为了防止某些类型的边信道跨网站跟踪,Chrome 已将大多数存储空间和通信 API 划分到第三方上下文中。

实现状态

我们已为使用 Chrome 115 及更高版本的所有用户启用此功能。存储空间分区提案可供进一步讨论。

什么是存储分区?

为了防止某些类型的边信道跨网站跟踪,Chrome 会在第三方上下文中对存储空间和通信 API 进行分区。

如果不进行存储分区,网站可以联接不同网站中的数据,以便在网络上跟踪用户。此外,它还允许嵌入式网站使用边信道技术(例如时间攻击XS-LeaksCOSI)推断顶级网站中用户的特定状态。

过去,存储空间仅按来源设置键值。这意味着,如果 a.comb.com 中嵌入了 example.com 中的 iframe,它可以通过存储 ID 并从存储空间中成功检索 ID,了解您在这些网站上的浏览习惯。启用第三方存储分区后,example.com 的存储空间位于两个不同的分区中,一个用于 a.com,另一个用于 b.com

分区通常意味着,iframe 通过存储 API(例如 localStorage 和 IndexedDB)存储的数据将不再可供同一源中的所有上下文访问。相反,这些数据仅适用于具有相同来源和相同顶级网站的情境。

之前

不进行分区的存储 API 示意图。
在存储分区之前,example.com 可以在嵌入到 a.com 时写入数据,然后在嵌入到 b.com 时读取这些数据。

之后

带分区的存储 API 示意图。
存储空间分区后,当 example.com 嵌入到 b.com 中时,如果 example.com 嵌入到 a.com 中,则无法访问 example.com 的存储空间。

链接的 iframe 上的存储分区

当 iframe 包含 iframe 时,情况会变得更加复杂。如果同一来源出现在链中的多个位置,这种情况尤为如此。

例如,A1 包含 B 的 iframe,B 包含 A2 的 iframe,并且 A1 和 A2 位于同一网站上。如果我们在进行分区时仅考虑顶级上下文和当前上下文,则 iframe A2 可以被视为第一方,因为它与顶级上下文 (A1) 位于同一网站上,尽管存在中介第三方 iframe (B)。如果 A2 默认有权访问未分区的存储空间,则可能会导致 A2 面临点击劫持等安全风险。

为解决此问题,Chrome 在存储分区键中添加了额外的“祖先位”,如果当前上下文和顶级上下文之间的任何文档与当前上下文跨网站,则会设置此位。在本例中,网站 B 是跨网站的,因此系统会为 A2 设置该位,并将其存储空间从 A1 分区。

如果链中没有跨网站上下文,则存储空间不会分区。例如,如果网站 A1 包含 A2 的 iframe,而 A2 包含 A3 的 iframe,则系统不会针对 A1、A2 或 A3 进行分区,因为它们都位于同一网站上。

对于需要跨链接的 iframe 实现非分区访问的网站,Chrome 正在尝试扩展 Storage Access API 以实现此用例。由于 Storage Access API 要求嵌套的网站明确调用该 API,因此这会降低点击欺骗风险。

更新后的 API

受分区影响的 API 可分为以下几类:

Storage API

  • 配额系统
    配额系统用于确定为存储分配了多少磁盘空间。配额系统会将每个分区视为一个单独的分桶,以确定允许的空间大小以及清除空间的时间。
    navigator.storage.estimate() 会返回分区的相关信息。仅限 Chrome 的 API(例如 window.webkitStorageInfonavigator.webkitTemporaryStorage)将被弃用。
    IndexedDB缓存存储使用新的分区配额系统。
  • Web Storage API
    Web Storage API 提供了浏览器可以通过的机制来存储键值对。有两种机制:本地存储会话存储。它们目前不受配额管理,但仍会进行分区。
  • 源私有文件系统
    File System Access API 允许网站在用户授予访问权限后,直接读取或保存对设备上文件和文件夹的更改。源私有文件系统允许来源将私密内容存储到磁盘,这些内容可供用户轻松访问且已分区。
  • Storage Bucket API
    Storage Bucket API 正在为 Storage 标准开发,该标准通过使用名为存储分区的新概念,整合了 IndexedDB 和 localStorage 等各种存储 API。存储在存储分区中的数据以及与存储分区关联的元数据会进行分区。
  • Clear-Site-Data 标头
    在响应中添加 Clear-Site-Data 标头后,服务器可以请求清除存储在用户浏览器中的数据。可以清除缓存、Cookie 和 DOM 存储空间。使用该标头只会清除一个分区中的存储空间。
  • Blob 网址存储区
    blob 是一种包含要处理的原始数据的对象,可以生成 blob 网址来访问资源。Blob 网址存储空间不会分区。 为了支持在顶级上下文中导航到任何 blob 网址的用例(讨论),blob 网址存储区可能会按代理集群(而非顶级网站)进行分区。此功能尚不可用于测试,并且分区机制未来可能会发生变化。

通信 API

除了存储 API 之外,允许一个上下文跨源边界进行通信的通信 API 也会进行分区。这些变更主要影响允许通过广播或同源集合点发现其他情境的 API。

对于以下通信 API,第三方 iframe 无法再与其同源上下文通信:

  • 广播频道
    Broadcast Channel API 允许浏览上下文(窗口、标签页或 iframe)与同源工作器之间进行通信。
    不建议更改在其中上下文关系明确定义的跨网站 iframe postMessage()
  • SharedWorker
    SharedWorker API 提供了一个可跨同一源的浏览上下文访问的工作器。
  • 网页锁定
    Web Locks API 允许在同一源的某个标签页或工作器中运行的代码在执行某项工作时为共享资源获取锁。

Service Worker API

Service Worker API 提供了用于在后台执行任务的接口。网站会创建永久性注册,以创建新的 worker 上下文来响应事件,并且该 worker 可以与任何同源上下文进行通信。此外,Service Worker API 可能会更改导航请求的时间,从而导致跨网站信息泄露,例如历史记录嗅探

因此,从第三方情境注册的 Service Worker 会被分区。

扩展程序 API

扩展程序是可让用户自定义浏览体验的程序。

扩展程序页面(采用 chrome-extension:// 架构的页面)可嵌入到网络上的网站中,在这种情况下,它们将继续拥有对其顶级分区的访问权限。这些网页还可以嵌入其他网站,在这种情况下,只要扩展程序对相应网站拥有主机权限,这些网站便可以访问其顶级分区。

如需了解详情,请参阅扩展程序文档

演示:测试存储分区

演示网站:https://storage-partitioning-demo-site-a.glitch.me/

演示网站的屏幕截图,显示每个测试的左侧均显示绿色对勾,右侧均显示红色叉号。
演示的屏幕截图,左侧显示了启用存储分区的浏览器的输出,右侧显示了未启用存储分区的浏览器的输出。

演示使用了两个网站:网站 A 和网站 B。

  • 当您在顶级上下文中访问网站 A 时,该网站会使用各种存储方法设置数据。
  • 网站 B 嵌入了网站 A 中的某个网页,而该嵌入会尝试读取之前设置的存储选项。
  • 当网站 A 嵌入到网站 B 中时,在存储空间分区后,网站 A 将无法访问这些数据,因此读取会失败。
  • 该演示使用每次读取的成功或失败情况来显示数据是否已分区。

目前,您可以使用 --disable-features=ThirdPartyStoragePartitioning 命令行开关在 Chrome 中关闭存储分区。

您还可以通过相同的方式测试其他浏览器,以查看它们的分区状态。

互动和分享反馈