存储分区

为防止出现某些类型的边信道跨渠道跟踪,Chrome 已在第三方环境中对大多数存储和通信 API 进行了分区。

实现状态

已在 Chrome 115 及更高版本中为所有用户启用此功能。存储分区方案可公开进行进一步讨论。

如果网站没有时间实现对第三方存储分区的支持,可以参与暂时取消分区的弃用试用(通过同源政策继续隔离,但取消顶级网站的隔离),并恢复其网站上嵌入的内容中 Storage、Service Worker 和通信 API 的先前行为。

什么是存储分区?

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

如果没有存储分区,网站可以将不同网站的数据联接起来,以在网络上跟踪用户。此外,它还允许嵌入式网站使用旁路技术(如计时攻击XS 泄露COSI)在顶级网站中推断出用户的特定状态。

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

通常,分区意味着同一来源中的所有上下文无法再访问由本地存储和 IndexedDB 等存储 API 通过 iframe 存储的数据。相反,这些数据仅适用于具有相同来源和同一顶级网站的上下文。

之前

未进行分区的存储 API 的示意图。
在存储分区之前,example.com 可以先写入 a.com 中的数据,然后在 b.com 上读取数据。

之后

具有分区功能的存储 API 的示意图。
存储空间分区之后,嵌入在 b.com 中的 example.com 嵌入 a.com 时无法访问 example.com 的存储空间。

链式 iframe 上的存储分区

当 iframe 包含 iframe 时,情况就会开始变得更加复杂。当同一出发地出现在链中的多个位置时尤其如此。

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

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

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

对于需要跨链式 iframe 进行未分区访问的网站,Chrome 正在尝试扩展 Storage Access API 以支持此用例。由于 Storage Access API 要求加框网站显式调用该 API,因此这样可以降低点击劫持风险。

更新后的 API

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

Storage API

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

通信 API

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

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

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

Service Worker API

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

因此,从第三方上下文注册的 Service Worker 会进行分区。

Extension API

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

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

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

演示:测试存储分区

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

演示网站的屏幕截图,其中每个测试的左侧都是绿色对勾,右侧是红色十字。
此演示的屏幕截图,其中显示了左侧有存储分区,右侧没有存储分区的浏览器的输出。

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

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

目前,您可以在 Chrome 中关闭存储分区,方法是将 chrome://flags/#third-party-storage-partitioning Chrome 标志设置为 disabled,以确认此操作未通过分区测试。

您也可以采用相同的方式测试其他浏览器,以查看其分区状态。

互动和分享反馈