状态分区

状态分区是 Mozilla 正在进行的一项广泛努力,旨在重新设计 Firefox 管理客户端状态(即存储在浏览器中的数据)的方式,以降低网站利用状态进行跨站点跟踪的能力,例如通过 第三方 Cookie

这项努力旨在通过为用户访问的每个网站提供一个分区存储位置来实现这一目标。本文概述了该机制,列出了受影响的 API,并说明如何调试受影响的网站。

状态分区目前在 Firefox Nightly 通道中默认启用。自 Firefox 85 版本起,状态分区工作的一部分(即 网络分区)已在 Firefox 的发行版通道中默认启用。

动机

使用共享状态进行跨站点跟踪

浏览器传统上通过资源加载位置的来源(或有时是可注册域名)来键入客户端状态。例如,可用于从 https://example.com/hello.html 加载的 iframe 的 Cookie、localStorage 对象和缓存将以 example.com 为键。无论浏览器当前是以第一方资源还是嵌入的第三方资源的形式加载来自该域的资源,情况都是如此。跟踪器利用这种跨站点状态来存储用户标识符并在网站之间访问它们。下面的示例显示了 example.com 如何使用其跨站点状态(在本例中为 Cookie)来跟踪用户在其自己的网站以及 A.exampleB.example 上的活动。

An example of cross-site state

过去阻止跨站点跟踪的方法

Firefox 过去实施的 Cookie 策略试图通过在特定条件下阻止某些域访问某些存储 API(例如,Cookie 和 localStorage)来减轻跟踪问题。例如,我们的“阻止所有第三方 Cookie”策略会阻止所有域在第三方上下文中访问某些存储 API。我们目前的 默认 Cookie 策略 仅在第三方上下文中阻止对分类为跟踪器的域的访问。

状态分区

状态分区是防止跨站点跟踪的一种不同方法。Firefox 不会在第三方上下文中阻止访问某些有状态 API,而是为嵌入的资源提供每个顶级网站的独立存储桶。更具体地说,Firefox 通过被加载资源的来源顶级网站 来对所有客户端状态进行双重键入。在大多数情况下,顶级网站是用户正在访问的顶级页面的方案和 eTLD+1

在下面的示例中,example.com 嵌入在 A.exampleB.example 中。但是,由于存储已分区,因此存在三个独立的存储桶(而不是一个)。跟踪器仍然可以访问存储,但由于每个存储桶都附加了顶级网站的键,因此它在 A 上访问的数据将不同于在 B 上访问的数据。这将阻止跟踪器在直接访问时将其标识符存储在 Cookie 中,然后在嵌入在其他网站中时检索该标识符。

An example of state partitioning

标准化

隐私社区小组 有一个关于 客户端存储分区 的工作项目。它概述了各个受影响标准中存储分区的标准化工作。我们打算将我们的状态分区实现与这些工作项目标准化后的结果保持一致。

Firefox 中分区的状态

静态分区

存储分区

为了防止 JavaScript 可访问的存储 API 被用于跨站点跟踪,可访问的存储将按顶级网站进行分区。这种机制意味着,通常情况下,嵌入在一个顶级网站中的第三方无法访问存储在另一个顶级网站下的数据。

存储 API

网络分区

与网络相关的 API 不打算用于网站存储数据,但它们可能会被 滥用 来进行跨站点跟踪。因此,以下网络 API 和缓存将永久按顶级网站进行分区。

注意:网络分区是永久性的。网站无法控制或放松这些限制。

网络 API

  • HTTP 缓存
  • 图像缓存
  • 网站图标缓存
  • 连接池
  • 样式表缓存
  • DNS
  • HTTP 身份验证
  • Alt-Svc
  • 推测连接
  • 字体和字体缓存
  • HSTS
  • OCSP
  • 中间 CA 缓存
  • TLS 客户端证书
  • TLS 会话标识符
  • 预取
  • 预连接
  • CORS 预检 缓存
  • WebRTC 设备 ID

动态分区

通常,如果可访问的存储按顶级网站分区,则如果支持存储访问 API,则仍然可以授予对第三方的未分区 Cookie 的访问权限

  • 使用 存储访问 API
  • 自动授予,例如,为提供联合登录的第三方授予访问权限。

有关自动授予的详细信息,请参阅 存储访问启发式 部分。

动态分区 API

存储访问启发式

为了提高网页兼容性,Firefox 目前包含一些启发式方法,用于自动授予未分区 Cookie 的访问权限给接收用户交互的第三方。这些启发式方法旨在允许网页上常见的某些第三方集成继续正常运行。

警告:存储访问启发式方法是一种过渡功能,旨在防止网站出现故障。它们不应被用于当前和未来的网页开发。

打开者启发式方法

  • 当一个分区后的第三方打开一个具有 打开者访问权限 的弹出窗口时,该第三方将获得对其嵌入者的存储访问权限,有效期为 30 天。
  • 当一个第一方 a.example 打开一个第三方弹出窗口 b.example 时,b.example 将获得对 a.example 的第三方存储访问权限,有效期为 30 天。

注意:对于滥用这些启发式方法进行跟踪目的的第三方,我们可能需要用户与弹出窗口进行交互,然后才会授予存储访问权限。

重定向启发式方法

  • 如果网站 b.example 重定向到 a.example,则 b.example 将获得对其嵌入者 a.example 的存储访问权限,前提是 a.exampleb.example 都在过去 10 分钟内被访问过并进行过交互。此存储访问权限将授予 15 分钟。
  • 如果跟踪器 tracker.example(由增强型跟踪保护分类)重定向到非跟踪器 a.example,并且 tracker.example 在过去 45 天内作为第一方接收过用户交互,则 tracker.example 将获得对 a.example 的存储访问权限,有效期为 15 分钟。

存储访问 API

第三方框架可以使用 document.requestStorageAccess 通过 存储访问 API 请求对 Cookie 的未分区访问权限。一旦获得授权,请求方将获得对其所有第一方 Cookie 的访问权限(即,如果访问时是第一方,它将拥有的访问权限)。

警告:当授予存储访问权限时,仍然可能存在对分区存储的引用。但是,网站不应依赖于能够同时使用分区和未分区 Cookie。

调试

我们鼓励网站所有者测试他们的网站,特别是那些依赖于第三方内容集成的网站。Firefox 中有几个功能可以简化测试过程。

日志记录

以下是与第三方上下文中存储进行交互时记录到网页控制台的消息概述。在以下示例中,a.example 是嵌入第三方框架 b.example 的顶级网站。

原因 控制台消息
第三方框架的存储已分区 由于“b.example”是在第三方上下文中加载的,并且启用了存储分区,因此提供了分区后的 Cookie 或存储访问权限。
通过 存储访问启发式方法 授予对未分区 Cookie 的访问权限 自动授予“a.example”上“b.example”的第一方隔离的存储访问权限。
通过 StorageAccessAPI 授予对未分区 Cookie 的访问权限 已授予“a.example”上“b.example”来源的存储访问权限。

清除第三方存储访问权限

如果第三方 iframe 被授予对父级上下文的存储访问权限,Firefox 会设置一个权限。 要撤销访问权限,您可以通过“权限”部分下“跨站点 Cookie”中的站点信息面板清除权限。

测试偏好设置

警告:请确保在独立的 Firefox 配置文件中设置这些偏好设置,或在测试后重置它们。

禁用 Web 兼容性功能

privacy.antitracking.enableWebcompat 设置为 false禁用所有 ETP 和状态分区 Web 兼容性功能。 禁用这些功能在测试时很有用,以确保您的网站与 Firefox 中的状态分区机制完全兼容,并且不依赖于临时启发式算法。

pref 禁用的功能包括

禁用启发式算法

以下偏好设置可用于通过配置编辑器禁用各个存储访问启发式算法

  • 启用/禁用重定向启发式算法privacy.restrict3rdpartystorage.heuristic.recently_visitedprivacy.restrict3rdpartystorage.heuristic.redirect
  • 启用/禁用窗口打开启发式算法privacy.restrict3rdpartystorage.heuristic.window_openprivacy.restrict3rdpartystorage.heuristic.opened_window_after_interaction

禁用网络分区

可以使用 privacy.partition.network_state pref 禁用网络分区。

禁用动态状态分区

要为所有网站禁用动态存储分区,可以使用 network.cookie.cookieBehavior pref

描述
5 拒绝(已知)跟踪器并分区第三方存储。
4 仅拒绝跟踪器(存储分区已禁用)。
0 允许所有

从分区中排除特定来源

也可以使用 privacy.restrict3rdpartystorage.skip_list 偏好设置,为特定来源禁用动态状态分区。 此 pref 包含一个以逗号分隔的来源列表以排除。 pref 值应遵循以下格式 first-party_origin_1,third-party_origin_1;first-party_origin_2,third-party_origin_2;...

例如,要为 example.com 上的 tracker.examplenews.example 上的 social.example 禁用分区,您可以将 pref 设置为以下内容

https://tracker.example,http://example.com;https://social.example,https://news.example