禁用第三方 Cookie

跨域(cross-origin) 和 跨站(cross-site)

跨域 cross-origin

同源:协议、主机、端口都一致

cross-origin

(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。

跨站 cross-site

同站:具有相同 eTLD+1,即相同的协议+相同的二级域名

https://a.xxx.com 和 https://b.xxx.com 相同的二级域名,是同站

tld+1

cross-site

SameSite

Chrome 51 起,Cookie 新增 SameSite 属性,用来防止 CSRF 攻击 (安全) 和用户追踪 (隐私)。

  • Strict(严格):当设置为 Strict 时,浏览器将只在当前网页的域名与 Cookie 所属的域名完全一致的情况下才发送该 Cookie 。

  • Lax(宽松):当设置为 Lax 时,浏览器将在导航到目标网页的情况下发送 Cookie,但仅限于顶级导航(如点击链接或通过 URL 导航)。在跨域的 POST 请求或通过 iframe 加载的请求中,浏览器将不会发送 Cookie。

  • None(无):当设置为 None 时,浏览器将始终发送 Cookie,无论请求是同站点还是跨站点。但是,要使用 None 值,还需要同时设置 Secure 属性,以确保仅在使用 HTTPS 安全连接时发送 Cookie。

Chrome 80 起,默认会给第三方 Cookie 添加 SameSite=Lax 属性,A 域名跨域请求 B 域名,不会携带 Cookie。 如果要使用三方 Cookie,需显式设置 SameSite=None; Secure

Chrome 118 开始有第三方 Cookie 的警告,2024 年 Q1-Q3 逐步禁用 SameSite=None; Secure,请求时无法读取并携带 SameSite=None;Secure 的 Cookie,响应 Set-Cookie: xxx=xx;SameSite=None;Secure 时也无法写入

影响范围?

测试设置位于 chrome://flags/#test-third-party-cookie-phaseout

  • 前端监控:上报的接口为跨站接口,通过三方 Cookie 来存储一个用户标识;
  • 统一登录:通过统一的跨站 SSO 接口为网站实现单点登录能力,共享用户身份;
  • 广告业务:通过三方 Cookie 存储用户标识,用于进行广告归因或兴趣推荐;
  • CSRF :通过 Cookie 存储 CSRF Token 信息,跨站请求则为三方 Cookie;
  • iframe:通用的聊天、地图等 iframe,通过三方 Cookie 来共享一些状态;

解决方案?

1. 变更携带位置+存储位置

不用 Cookie 和 Set-Cookie,改成其他地方,携带位置改到 query、请求头、请求体,存储位置改到 localStorage、sessionStorage、indexDB 等

优点: 自由度高

缺点: 改动较大

2. 服务端代理

例如在 a.com 域名发起请求 b.com/update ,代理将调用改写为 a.com/proxy/b.com/update

优点:略微减少了改造成本

缺点: 改动较大,服务端流量,增加成本

让三方 iframe 嵌入发起的跨站请求的依然可以携带三方 Cookie

解决三方 Cookie 问题的提案中,其实还有一个提案是 SameParty,意味标记同一方的 Cookie。最终采纳的是 Partitioned,不过可以达到差不多的效果。

partitioned

通过设置 Partitioned,就可以将站点选择将 Cookie 存储在由顶级站点分区的单独 Cookie jar 中。比如我们在站点 A 中通过 iframe 嵌入了一个站点 C,正常情况下如果三方 Cookie 被禁用后,C 是无法在 A 站点访问到它的 Cookie 的。如果 C 在它的 Cookie 上指定了 Partitioned 属性,这个 Cookie 将保存在一个特殊的分区 jar 中。 它只会在站点 A 中通过 iframe 嵌入站点 C 时才会生效,浏览器会判定只会在顶级站点为 A 时才发送该 Cookie。当用户访问一个新站点时,例如站点 B,如果也它通过 iframe 嵌入了站点 C,这时在站点 B 下的站点 C 是无法访问到之前在 A 下面设置的那个 Cookie 的。如果用户直接访问站点 C ,一样也是访问不到这个 Cookie 的。

解决同一个公司或组织下不同域名的数据共享能力。

可以将多个站点标记为一方, 例如 taobao.com 和 tmail.com 同样属于阿里, 可以标记为同一方

除了把这个站点在自己的网站下部署一份,有点奇葩的是我们还需要通过 PR 将其 Google 提供的 相关网站集 GitHub 存储库。然后站点可以使用 Storage Access API 通过 requestStorageAccess() 请求访问跨站点 Cookie ,或使用 requestStorageAccessFor() 委托访问。当站点位于同一组内时,浏览器将自动授予访问权限,并且跨站点 Cookie 是可用的。

5. Attribution Reporting API

在不追踪用户跨站活动的情况下,提供跨站点的广告归因、转化分析能力。

使用方式大概是这样的:我们首先需要提供一个用于存储归因报告数据的接口,然后在 HTML a、img 、iframe 等标签上追加 attributionsrc:

<a
  href="https://shoes.example/landing"
  attributionsrc="http://adtech.example/register-source?..."
  target="_blank"
>
  Click me</a
>

<img
  href="https://advertiser.example/landing"
  attributionsrc="https://adtech.example/register-source?..."
/>

或者通过 JavaScript 调用注入 attribution src:

const encodedUrl = encodeURIComponent('https://adtech.example/attribution_source?ad_id=...');
window.open(
  "https://shoes.example/landing",
  "_blank",
  attributionsrc=${encodedUrl});

6. Topics API

在不依赖三方 Cookie 的情况下由浏览器进行用户的兴趣推断。

通过 Topics API ,浏览器可以根据用户的浏览活动观察并记录用户感兴趣的主题。这些信息只会记录在用户的设备上。然后,Topics API 可以让 API 调用者(例如广告技术平台)访问用户感兴趣的主题,但不会透露有关用户浏览活动的其他信息。

const topics = await document.browsingTopics();

7. Shared Storage API

在保护用户隐私的场景下支持跨站点信息存储和读取。

像其他 JavaScript 存储 API(例如 localStorage 或 indexedDB)一样,我们可以随时写入 Shared Storage ,但区别是我们只能在一个安全的环境(shared storage worklet)中读取共享存储的值。

8. FedCM

提供一种标准化的方式进行用户身份验证和凭据管理。

FedCM(联合凭证管理)是联合身份服务(例如“使用...登录”)的一种隐私保护方法,用户可以通过该方法登录网站,而无需与身份服务或网站共享其个人信息。

附录

  1. SameSite: Lax 下请求
请求类型示例正常情况Lax
链接<a href="..."></a>发送 Cookie发送 Cookie
预加载<link rel="prerender" href="..."/>发送 Cookie发送 Cookie
GET 表单<form method="GET" action="..."> 发送 Cookie发送 Cookie
POST 表单<form method="POST" action="...">发送 Cookie不发送
iframe<iframe src="..."></iframe> 发送 Cookie不发送
AJAX$.get("...") 发送 Cookie不发送
Image<img src="..."> 发送 Cookie不发送

Lax 主要解决 Strict 的易用性问题,用户从第三方页面访问一个已登录的系统时,由于未携带Cookie,总是需要重新登录。但由于现在基本上所有网站都是 SPA + ajax 请求,a 链接跳转携带的 Cookie 一般可以忽视

引用

本文主要为信息整理