具有独立分区状态 (CHIPS) 的 Cookie

允许开发者选择将 Cookie 存储在“分区”存储空间中,每个顶级网站都有单独的 Cookie Jar。

实现状态

浏览器支持

  • Chrome:114.
  • Edge:114。
  • Firefox:131.
  • Safari:不受支持。

来源

什么是 CHIPS?

借助具有独立分区状态的 Cookie (CHIPS),开发者可以选择将 Cookie 存储在分区存储空间中,每个顶级网站都有单独的 Cookie Jar,从而改善用户隐私和安全。

如果不进行分区,第三方 Cookie 可以让服务跟踪用户,并联接来自许多不相关顶级网站的用户信息。这称为跨网站跟踪。

当第三方 Cookie 被屏蔽时,CHIPS、Storage Access API相关网站集是从跨网站上下文(例如 iframe)读取和写入 Cookie 的唯一方式。

显示如何在两个不同的网站之间共享 Cookie 的示意图。
如果不进行 Cookie 分区,第三方服务在嵌入到一个顶级网站时可以设置 Cookie,并在该服务嵌入到其他顶级网站时访问该 Cookie。

CHIPS 引入了新的 Cookie 属性 Partitioned,以支持按顶级上下文进行分区的跨网站 Cookie。

Set-Cookie 标头:

Set-Cookie: __Host-name=value; Secure; Path=/; SameSite=None; Partitioned;

JavaScript:

document.cookie="__Host-name=value; Secure; Path=/; SameSite=None; Partitioned;"

分区第三方 Cookie 会与其最初设置的顶级网站相关联,且无法从其他位置访问。这样,第三方服务设置的 Cookie 只能在其最初设置的顶级网站的同一嵌入式环境中读取。

示意图:两个嵌入了共同第三方的不同网站将不再共享该第三方的 Cookie。
启用 Cookie 分区后,如果第三方服务在嵌入到一个顶级网站时设置了 Cookie,那么当该服务嵌入到其他顶级网站时,将无法访问该 Cookie。

使用分区 Cookie 时,当用户访问网站 A 且来自网站 C 的嵌入内容设置了具有 Partitioned 属性的 Cookie 时,该 Cookie 会保存在一个分区 jar 中,该 jar 仅用于存储网站 C 在嵌入到网站 A 时设置的 Cookie。只有当顶级网站为 A 时,浏览器才会发送该 Cookie。

当用户访问新网站(例如网站 B)时,嵌入的 C 框架不会收到在网站 A 中嵌入 C 时设置的 Cookie。

如果用户以顶级网站的身份访问网站 C,则 C 在嵌入到 A 中时设置的分区 Cookie 也不会随该请求一起发送。

示意图:当同一第三方嵌入到两个不同的网站中时,Cookie 不会共享。
启用 Cookie 分区后,在嵌入到网站中时设置 Cookie 的第三方服务将无法访问该 Cookie,即使用户以顶级网站的身份访问该服务也是如此。

使用场景

例如,网站 retail.example 可能希望与第三方服务 support.chat.example 合作,在其网站上嵌入支持聊天框。目前,许多可嵌入的聊天服务都依赖 Cookie 来保存状态。

显示嵌入聊天 widget 的网站的示意图
顶级网站 retail.example 嵌入了第三方服务 support.chat.example

如果无法设置跨网站 Cookie,support.chat.example 就需要找到其他(通常更复杂)的方法来存储状态。或者,需要将其嵌入到顶级网页中,但这会带来风险,因为这会允许 support.chat.example 脚本在 retail.example 上拥有提升的权限,例如能够访问身份验证 Cookie。

CHIPS 提供了一种更简单的选项,可让您继续使用跨网站 Cookie,而无需担心与未分区的 Cookie 相关的风险。

CHIPS 的示例用例包括以下任何场景:跨网站子资源需要某种会话或持久性状态的概念,该概念的范围限定为单个顶级网站上的用户活动,例如:

  • 第三方聊天嵌入
  • 第三方地图嵌入
  • 第三方付款嵌入
  • 子资源 CDN 负载均衡
  • 无头 CMS 提供商
  • 用于分发不可信用户内容的沙盒网域(例如 googleusercontent.com 和 githubusercontent.com)
  • 使用 Cookie 来提供受第一方网站上的身份验证状态控制的访问权限内容的第三方 CDN(例如,托管在第三方 CDN 上的社交媒体网站上的个人资料照片)
  • 依赖于在请求中使用 Cookie 的远程 API 的前端框架
  • 需要按发布商设置状态级范围的嵌入式广告(例如,捕获用户对相应网站的广告偏好设置)

为什么 CHIPS 使用“用户选择启用”分区模型

在访问未分区的第三方 Cookie 被阻止的情况下,我们尝试了几种其他分区方法。

Firefox 宣布,在其 ETP 严格模式和无痕浏览模式下,默认会对所有第三方 Cookie 进行分区,因此所有跨站 Cookie 都会按顶级网站进行分区。不过,如果在未经第三方用户选择的情况下对 Cookie 进行分区,可能会导致意外 bug,因为某些第三方服务构建了预期使用未分区的第三方 Cookie 的服务器。

Safari 之前曾尝试根据启发词语对 Cookie 进行分区,但最终选择完全屏蔽 Cookie,并将开发者困惑作为原因之一。最近,Safari 表示有意采用基于用户选择的模型

CHIPS 与现有分区 Cookie 实现的不同之处在于,第三方需要选择启用。在(未分区)第三方 Cookie 过时后,必须使用新属性设置 Cookie,才能在跨平台请求中发送 Cookie。

虽然第三方 Cookie 仍然存在,但 Partitioned 属性可让您选择启用更严格、更安全的 Cookie 行为。CHIPS 是一项重要的举措,有助于服务顺利过渡到不使用第三方 Cookie 的未来。

目前,Cookie 的键是设置它们的网站的主机名或域名,即其主机密钥

例如,对于来自 https://support.chat.example 的 Cookie,主机键为 ("support.chat.example")

在 CHIPS 下,选择启用分区的 Cookie 将在其主机键和分区键上使用双重密钥。

Cookie 的分区键是浏览器在向设置 Cookie 的端点发出请求之初所访问的顶级网址的网站(架构和可注册网域)。

在前面的示例中,https://support.chat.example 嵌入在 https://retail.example 中,因此顶级网址为 https://retail.example

在这种情况下,分区键为 ("https", "retail.example")

同样,请求的分区键是浏览器在请求开始时访问的顶级网址的网站。浏览器只能在请求中发送具有 Partitioned 属性的 Cookie,且请求的分区键与该 Cookie 相同。

下面是前面示例中 Cookie 键在启用 CHIPS 前后的情况。

网站 A 和嵌入的网站 C 共用一个分区 Cookie。如果未嵌入,网站 C 将无法访问分区 Cookie。
网站 A 和嵌入的网站 C 共享一个分区 Cookie。如果未嵌入,网站 C 将无法访问分区 Cookie。

CHIPS 之前

key=("support.chat.example")

CHIPS 之后

key={("support.chat.example"),("https", "retail.example")}

安全设计

为了鼓励采用良好的安全做法,在 CHIPS 中,Cookie 只能通过安全协议设置和发送。

  • 必须使用 Secure 设置分区 Cookie。
  • 建议在设置分区 Cookie 时使用 __Host- 前缀,以将其绑定到主机名(而非可注册网域)。

示例:

Set-Cookie: __Host-example=34d8g; SameSite=None; Secure; Path=/; Partitioned;

CHIPS 的替代方案

Storage Access API 和关联的相关网站集 (RWS) 是 Web 平台机制,可用于出于特定面向用户的用途而实现有限的跨网站 Cookie 访问权限。

这些是 CHIPS 分区的替代方案,在这些方案中,需要访问跨网站的未分区 Cookie。

如果您需要将同一 Cookie 提供给嵌入在多个相关网站中的服务,不妨考虑使用 Storage Access API 和相关网站集。

CHIPS 可让服务在多个网站中充当隔离的组件,而无需在多个网站中使用相同的 Cookie。如果该服务设置了分区 Cookie,其分区键将是顶级网站,并且该 Cookie 将不适用于也使用该服务的其他网站。

“相关网站集”设计依赖于 Storage Access API,并且未与 CHIPS 分区集成。如果您的用例依赖于 RWS 中各个网站之间的共享 Cookie 分区,您可以在 GitHub 问题中提供示例和反馈

演示

演示将向您详细介绍分区 Cookie 的运作方式,以及如何在 DevTools 中检查这些 Cookie。

网站 A 嵌入了来自网站 B 的 iframe,该 iframe 使用 JavaScript 设置了两个 Cookie:分区 Cookie 和非分区 Cookie。网站 B 会显示可通过该位置使用 document.cookie 访问的所有 Cookie。

当第三方 Cookie 被屏蔽时,网站 B 只能在跨网站情境中设置和访问具有 Partitioned 属性的 Cookie。

允许使用第三方 Cookie 后,网站 B 也能够设置和访问未分区的 Cookie。

网站 A 和网站 B
左侧:第三方 Cookie 已被屏蔽。正确:允许使用第三方 Cookie。

前提条件

  1. Chrome 118 或更高版本。
  2. 访问 chrome://flags/#test-third-party-cookie-phaseout 并启用此设置

使用开发者工具检查分区 Cookie

  1. 访问 https://chips-site-a.glitch.me
  2. Control+Shift+J(在 Mac 上,按 Command+Option+J)打开 DevTools。
  3. 点击 Application(应用)标签页。
  4. 依次前往应用 > 存储 > Cookie
  5. 点击 https://chips-site-b.glitch.me

开发者工具将显示所选来源的所有 Cookie。

DevTools“Application”标签页中来自网站 B 的 Cookie。

网站 B 只能在跨网站上下文中设置分区 Cookie,未分区的 Cookie 将被屏蔽:

  • 您应该会看到 __Host-partitioned-cookie,其中包含顶级网站 https://chips-site-a.glitch.me 的分区键。
__Host-partitioned-cookie 的分区键。
  1. 点击前往网站 B
  2. 在 DevTools 中,依次前往 Application > Storage > Cookies
  3. 点击 https://chips-site-b.glitch.me
网站 B
在顶级,网站 B 可以看到所有 Cookie(分区 Cookie 和非分区 Cookie)

在此场景中,由于您在顶级情境中的网站 B 上,因此该网站可以设置和访问这两个 Cookie:

  • unpartitioned-cookie 的分区键为空。
  • __Host-partitioned-cookie Cookie 具有分区键 https://chips-site-b.glitch.me
在 DevTools 的“Application”标签页中,以顶级网站访问网站 B 时,该网站的 Cookie。__Host-partitioned-cookie 的分区键为 https://chips-site-b.glitch.me。

如果您返回到网站 A,unpartitioned-cookie 现在会存储在浏览器中,但无法从网站 A 访问。

  1. 点击前往网站 A
  2. 点击网络标签页。
  3. 点击 https://chips-site-b.glitch.me
  4. 点击 Cookies 标签。

在网站 A 上,您应该会看到具有顶级网站 https://chips-site-a.glitch.me 的分区键的 __Host-partitioned-cookie

“网络”标签页,显示网站 B iframe 中的 Cookie,这些 Cookie 在网站 A 中嵌入后可供访问。

如果您选中显示滤除的 Cookie 请求,DevTools 将显示未分区的 Cookie 已被屏蔽,并以黄色突出显示,并显示提示:“此 Cookie 因用户偏好设置而被屏蔽”

“网络”标签页,显示来自网站 B iframe 的已屏蔽 Cookie。

Application > Storage > Cookies 中,点击 https://chips-site-b.glitch.me 会显示:

  • unpartitioned-cookie 使用空分区键。
  • 分区键为 https://chips-site-a.glitch.me__Host-partitioned-cookie Cookie。
DevTools 的“Application”标签页中显示了来自网站 B 的 Cookie。__Host-partitioned-cookie Cookie 具有分区键 https://chips-site-a.glitch.meunpartitioned-cookie 会显示,但当它嵌入在网站 A 上时,网站 B iframe 无法访问它。

清除 Cookie

如需重置演示,请清除该网站的所有 Cookie:

  • Control+Shift+J(在 Mac 上,按 Command+Option+J)打开 DevTools。
  • 点击 Application(应用)标签页。
  • 依次前往应用 > 存储 > Cookie
  • 右键点击 https://chips-site-b.glitch.me
  • 点击清除

资源