状态分区
状态分区 是 Mozilla 的一项广泛举措,旨在重新设计 Firefox 如何管理客户端状态(即浏览器中存储的数据),以减轻网站滥用状态进行跨站点跟踪的能力,例如通过 第三方 cookie。
这项工作旨在通过为用户访问的每个网站提供一个分区存储位置来实现。本文概述了该机制,列出了受影响的 API,并解释了如何调试受影响的站点。
从 Firefox 103 开始,状态分区默认开启。
动机
使用共享状态进行跨站点跟踪
浏览器传统上通过资源加载来源的域(或有时是可注册域)来键合客户端状态。例如,从 https://example.com/hello.html 加载的 iframe 可用的 cookie、localStorage 对象和缓存将由 example.com 键合。无论浏览器当前是否以第一方资源或嵌入的第三方资源加载该域的资源,都是如此。跟踪器利用这种跨站点状态来存储用户标识符并在网站之间访问它们。下面的示例显示了 example.com 如何利用其跨站点状态(在本例中为 cookie)来跟踪用户在其自己的网站以及 A.example 和 B.example。

过去阻止跨站点跟踪的方法
Firefox 过去针对 cookie 的策略试图通过在某些条件下阻止访问某些存储 API(例如 cookie 和 localStorage)来缓解跟踪。例如,我们的“阻止所有第三方 cookie”策略将阻止所有域在第三方上下文中加载时访问某些存储 API。我们当前的 默认 cookie 策略仅针对被归类为跟踪器的域在第三方上下文中阻止访问。
状态分区
状态分区是防止跨站点跟踪的一种不同方法。Firefox 没有在第三方上下文中阻止对某些有状态 API 的访问,而是为每个顶级网站提供的嵌入式资源提供独立的存储桶。更具体地说,Firefox 通过加载资源的源和顶级站点对所有客户端状态进行双重键合。在大多数情况下,顶级站点是用户访问的顶级页面的方案和 eTLD+1。
在下面的示例中,example.com 被嵌入到 A.example 和 B.example 中。但是,由于存储已分区,因此有三个不同的存储桶(而不是一个)。跟踪器仍然可以访问存储,但由于每个存储桶都在顶级站点下进行了额外的键合,因此它在 A 上可以访问的数据与在 B 上可以访问的数据不同。这将阻止跟踪器在直接访问时在其 cookie 中存储标识符,然后在嵌入到其他网站时检索该标识符。

标准化
隐私社区小组有一个针对 客户端存储分区的工作项。这提供了对各个受影响的标准中存储分区标准化工作的概述。随着工作项的标准化,我们打算将我们的状态分区实现与之保持一致。
Firefox 中分区的状态
静态分区
存储分区
为了防止 JavaScript 可访问的存储 API 被用于跨站点跟踪,可访问的存储按顶级站点进行分区。此机制意味着,一般来说,嵌入在一个顶级站点中的第三方无法访问在另一个顶级站点下存储的数据。
存储 API
网络分区
网络相关 API 的设计目的不是供网站存储数据,但它们可能被滥用进行跨站点跟踪。因此,以下网络 API 和缓存将由顶级站点永久分区。
注意:网络分区是永久性的。网站无法控制或放宽这些限制。
网络 API
动态分区
通常,如果可访问存储按顶级站点进行分区,则可以通过存储访问 API 授予对第三方未分区 cookie 的访问权限,前提是支持该 API。
- 使用 存储访问 API。
- 自动授予,例如,为提供联合登录的第三方。
有关自动授予的详细信息,请参阅存储访问启发式部分。
动态分区 API
存储访问启发式
为了提高 Web 兼容性,Firefox 目前包含一些启发式方法,可以自动授予在第三方接收用户交互时访问 cookie 的权限。这些启发式方法旨在允许 Web 上常见的某些第三方集成继续正常工作。
警告:存储访问启发式是一种过渡性功能,旨在防止网站中断。不应将其用于当前和未来的 Web 开发。
打开者启发式
当一个分区化的第三方打开一个具有打开者访问权限的弹出窗口,并且用户与该弹出窗口交互时,该第三方将获得对其嵌入方的存储访问权限,有效期为 30 天。
导航启发式
假设托管在 a.example 的站点在一个窗口中将用户导航到 b.example,用户与 b.example 交互,然后迅速导航回 a.example。在这种情况下,b.example 将获得作为 a.example 上的第三方 30 天的存储访问权限。
Storage Access API
第三方框架可以使用 document.requestStorageAccess 通过 存储访问 API 请求未分区 cookie 的访问权限。一旦授予,请求方将能够访问其所有第一方 cookie(即,如果作为第一方访问,它们将能够访问的 cookie)。
警告:授予存储访问权限时,仍可能存在对分区存储的引用。但是,网站不应依赖于同时使用分区和未分区 cookie。
调试
我们鼓励网站所有者测试他们的网站,特别是那些依赖第三方内容集成的网站。Firefox 中有几项功能可以使测试更容易。
日志记录
以下是与第三方上下文中的存储交互时记录到 Web 控制台的消息概述。在以下示例中,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 中的状态分区机制完全兼容,并且不依赖于临时启发式。
此首选项禁用的功能包括:
- 存储访问启发式:只能通过存储访问 API 获取对 cookie 的未分区访问。
- 自动存储访问授予:document.requestStorageAccess 将始终提示用户。
- SmartBlock 的“选择加入后解锁”功能,当用户与之交互时,允许某些跟踪器。SmartBlock 的“选择加入后解锁”功能,它会在用户与某些跟踪器交互时允许它们。
- 通过跳过列表机制授予网站的任何临时反跟踪例外。
禁用启发式
以下首选项可用于通过配置编辑器禁用单个存储访问启发式
- 启用/禁用导航启发式:
privacy.restrict3rdpartystorage.heuristic.navigation - 启用/禁用打开者启发式:
privacy.restrict3rdpartystorage.heuristic.opened_window_after_interaction
禁用网络分区
可以使用 privacy.partition.network_state 首选项禁用网络分区。
禁用动态状态分区
要为所有站点禁用动态存储分区,可以使用 network.cookie.cookieBehavior 首选项
| 值 | 描述 |
|---|---|
| 5 | 分区第三方存储。 |
| 4 | 拒绝跟踪器(存储分区已禁用)。 |
| 0 | 允许所有存储(存储分区已禁用)。 |
此首选项的其他值可能会完全禁用第三方存储。
豁免特定源进行分区
还可以使用 privacy.restrict3rdpartystorage.skip_list 首选项为特定源禁用动态状态分区。此首选项包含要豁免的源的逗号分隔列表。首选项值应遵循以下格式:first-party_origin_1,third-party_origin_1;first-party_origin_2,third-party_origin_2;...。
例如,要在 example.com 上的 tracker.example 或 news.example 上的 social.example 上禁用分区,您可以将首选项设置为以下值
https://example.com,https://tracker.example;https://news.example,https://social.example
您可以使用 * 作为第一个或第三方的通配符。例如,要在所有站点上禁用 videos.example 的分区,或者在 unpartitioned.example 上禁用所有分区,您可以将首选项设置为以下值
*,https://videos.example;unpartitioned.example,*