SameSite Cookie 说明

浏览器支持

  • Chrome: 51.
  • Edge: 16.
  • Firefox: 60.
  • Safari: 13.

来源

每个 Cookie 都包含一个键值对以及许多属性,这些属性控制何时何地使用该 Cookie。

引入 SameSite 属性(在 RFC6265bis 中定义)允许您声明您的 Cookie 是否仅限于第一方或同站点上下文。 准确理解此处的“站点”的含义很有帮助。 站点是域后缀和紧接在其之前的域部分的组合。 例如,www.web.dev 域是 web.dev 站点的一部分。

关键术语:如果用户在 www.web.dev 上并从 static.web.dev 请求图像,则这是一个同站点请求。

公共后缀列表定义了哪些页面算作在同一站点上。 它不仅取决于顶级域名(如 .com),还可以包括诸如 github.io 之类的服务。 这使得 your-project.github.iomy-project.github.io 可以算作不同的站点。

关键术语:如果用户在 your-project.github.io 上并从 my-project.github.io 请求图像,则这是一个跨站点请求。

使用 SameSite 属性声明 Cookie 用法

Cookie 上的 SameSite 属性提供了三种不同的方式来控制此行为。 您可以选择不指定属性,也可以使用 StrictLax 将 Cookie 限制为同站点请求。

如果您将 SameSite 设置为 Strict,则您的 Cookie 只能在第一方上下文中发送;也就是说,如果 Cookie 的站点与浏览器地址栏中显示的站点匹配。 因此,如果将 promo_shown Cookie 设置如下

Set-Cookie: promo_shown=1; SameSite=Strict

当用户在您的网站上时,Cookie 会按预期随请求一起发送。 但是,如果用户从另一个站点跟踪链接进入您的站点,则 Cookie 不会在初始请求中发送。 这对于与始终在初始导航之后的功能(例如更改密码或进行购买)相关的 Cookie 很有用,但对于像 promo_shown 这样的 Cookie 来说太严格了。 如果您的读者跟踪链接进入该站点,他们希望发送 Cookie,以便可以应用他们的偏好。

SameSite=Lax 允许浏览器通过这些顶级导航发送 Cookie。 例如,如果另一个站点引用您站点的内容,在这种情况下,通过使用您的猫照片并提供指向您的文章的链接,如下所示

<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>

使用设置为 Lax 的 Cookie,如下所示

Set-Cookie: promo_shown=1; SameSite=Lax

当浏览器为其他人的博客请求 amazing-cat.png 时,您的站点不会发送 Cookie。 但是,当读者跟踪链接到您站点上的 cat.html 时,该请求确实包含 Cookie。

我们建议以这种方式使用 SameSite,将影响网站显示的 Cookie 设置为 Lax,并将与用户操作相关的 Cookie 设置为 Strict

您还可以将 SameSite 设置为 None,以指示您希望在所有上下文中都发送 Cookie。 如果您提供其他站点使用的服务,例如小部件、嵌入式内容、联盟计划、广告或跨多个站点的登录,请使用 None 以确保您的意图明确。

Three cookies labelled None, Lax, or Strict depending on their context
将 Cookie 的上下文显式标记为 NoneLaxStrict

没有 SameSite 的默认行为的更改

浏览器支持

  • Chrome: 80.
  • Edge: 86.
  • Firefox: behind a flag.
  • Safari:不支持。

SameSite 属性得到广泛支持,但尚未得到广泛采用。 过去,在不使用 SameSite 的情况下设置 Cookie 默认在所有上下文中发送它们,这使用户容易受到 CSRF 和意外信息泄露的攻击。 为了鼓励开发者声明他们的意图并为用户提供更安全的体验,IETF 提案 Incrementally Better Cookies 提出了两个关键更改

  • 没有 SameSite 属性的 Cookie 被视为 SameSite=Lax
  • 带有 SameSite=None 的 Cookie 也必须指定 Secure,这意味着它们需要安全上下文。

这两个更改都向后兼容正确实施了先前版本 SameSite 属性的浏览器,以及不支持早期 SameSite 版本的浏览器。 它们的目的是通过使 Cookie 行为和预期用途显式化来减少开发者对浏览器默认行为的依赖。 任何无法识别 SameSite=None 的客户端都应忽略它。

默认 SameSite=Lax

如果您发送 Cookie 而不指定其 SameSite 属性,则浏览器会将该 Cookie 视为设置为 SameSite=Lax。 我们仍然建议显式设置 SameSite=Lax,以使您的用户体验在不同浏览器之间更加一致。

SameSite=None 必须是安全的

当您使用 SameSite=None 创建跨站点 Cookie 时,您还必须将它们设置为 Secure,浏览器才能接受它们

Set-Cookie: widget_session=abc123; SameSite=None; Secure

您可以从 Chrome 76 开始测试此行为,方法是启用 about://flags/#cookies-without-same-site-must-be-secure,从 Firefox 69 开始,方法是在 about:config 中设置 network.cookie.sameSite.noneRequiresSecure

我们还建议尽快将现有 Cookie 更新为 Secure。 如果您依赖于在您的站点上提供第三方内容的服务,请确保您的服务提供商更新他们的 Cookie,并更新您站点上的任何代码片段或依赖项,以确保它使用新的行为。

有关更新 Cookie 以成功处理 SameSite=None 的这些更改以及浏览器行为差异的更多详细信息,请参阅后续文章SameSite Cookie 食谱

感谢 Lily Chen、Malte Ubl、Mike West、Rob Dodson、Tom Steiner 和 Vivek Sekhar 的贡献和反馈。

Cookie 英雄图片由 Pille-Riin PriskeUnsplash 上提供