译:尝试用大白话解释SameSite Cookies

通过学习如何显式的标记 (译:指设置SameSite 跨站点Cookie (译:指cross-site cookies 来保护站点。
2019年5月7日 • 2020年5月28日更新

作者 • Rowan Merewood • 本文出处
作者twitter
作者github
译者主页

译者按: SameSite Cookies使用场景之一 —— 单点登录
具体如何使用 SameSite=None,请参阅第二部分: 食用SameSite Cookie

Cookies 是向web站点添加持久状态的可用方法之一。这些年来它的能力不断发展,但是给平台增加了一些遗留问题。为了解决这些问题,浏览器(包括Chrome,Firefox和Edge)正在更改他们自身的行为,强制实施(了)更多保存隐私信息的默认设置。

每个Cookie都是一个 key=value(译:指键值对) ,且含有一些设定浏览器(页面)何时和何处使用该Cookie的属性。您可能已经使用了这些属性来设置过期日期或指示Cookie只能通过HTTPS发送。服务器通过 Set-Cookie 在响应中发送适当命名的标头来设置Cookie 。有关所有详细信息您可以深入阅读RFC6265bis(译:关于IETF,但是现在这里快速回顾一下。

假设你有一个博客,你想向你的用户展示一个 “What’s new” 的推荐(广告)。用户可以撤销该推荐(广告),并且在一段时间内再也看不到它了。那么您可以通过将该首选项存储在Cookie中,并将其设置为在一个月(2,600,000秒)内到期,然后仅通过HTTPS发送。该标题看起来像这样(服务器使用Set-Cookie标题设置Cookie):

Set-Cookie: promo_shown=1; Max-Age=2600000; Secure

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mx7W25mY-1595833986452)(https://webdev.imgix.net/samesite-cookies-explained/set-cookie-response-header.png)]

当您的读者(用户)查看满足这些要求的页面时,也就是说,他们的连接是安全的,而且Cookie还不到一个月,,则他们的浏览器将在其请求中发送此标头:

Cookie: promo_shown=1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GjymqMSJ-1595833986454)(https://webdev.imgix.net/samesite-cookies-explained/cookie-request-header.png)]
您的浏览器将Cookie发送回Cookie标头。

您还可以使用来JavaScript的 document.cookie 来添加和读取该网站的Cookie, document.cookie 将创建或覆盖Cookie。例如,您可以在浏览器的JavaScript控制台中尝试以下操作:

> document.cookie = "promo_shown=1; Max-Age=2600000; Secure"
< "promo_shown=1; Max-Age=2600000; Secure"

读取 document.cookie 将输出当前上下文中可访问的所有Cookie,每个Cookie用分号分隔:

> document.cookie
< "promo_shown=1; color_theme=peachpuff; sidebar_loc=left"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZyegVDl-1595833986455)(https://webdev.imgix.net/samesite-cookies-explained/document-cookie.png)]

如果您在一些受欢迎的网站上尝试此操作(译:指使用document.cookie读取Cookie),您会注意到大多数网站设置的内容远远超过了三个Cookie。在大多数情况下,这些Cookie会在每个向该域(名)的请求中被发送,这有很多含义。对于用户来说,上传带宽通常比下载带宽受到更多的限制,因此所有出站请求的开销都是在第一个字节的时间上增加延迟。保守的设置的您站点Cookie的数量和大小。利用 Max-Age 属性有助于确保Cookie的停留时间不会超过您所需要的。

# 什么是第一方和第三方Cookie?

如果您回到以前选择的相同站点,您可能会注意到存在针对各种域(名)的Cookie,而不仅仅是您当前正在访问域(名)的Cookie。与当前站点的域(名)匹配的Cookie称为第一方 Cookie。同样,来自当前站点以外的域(名)的Cookie也称为第三方 Cookie。这不是一个绝对的标签,而是相对于用户的上下文;同一Cookie可以是第一方也可以是第三方,具体取决于用户当时所在的网站(Cookie可能来自一个页面上的各种不同的域)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ENBcOe15-1595833986457)(https://webdev.imgix.net/samesite-cookies-explained/cross-site-set-cookie-response-header.png)]

继续上面的示例,假设您的一篇博客文章中包含一张特别棒的猫的图片,该图片的地址是 /blog/img/amazing-cat.png 。因为这是一张很棒的图片,所以另一个人直接在他们的网站上使用它。如果访问者访问过您的博客并拥有 promo_shown 的Cookie,那么当他们在其他人的站点上查看 amazing-cat.png 时, promo_shown 的Cookie也会发送到该图片的请求中。promo_shown 的Cookie并不是对任何人都有意义,因为 promo_show 的Cookie在这个人的网站上不用于任何东西,这个Cookie只是增加了请求的开销。

在请求第三方的资源时,资源的请求头中携带第三方的cookie其实对我无用,无意义的Cookie增加了请求的开销也并不是我期望中的效果,那么浏览器为什么要这样做呢?其实,通过这种机制,站点可以在第三方上下文中使用时保持状态。例如,如果您在自己的网站上嵌入YouTube视频,且您的访问者已经登录YouTube,则访问者将在播放器中看到“稍后观看”选项。该会话将通过第三方Cookie(译:指YouTube的Cookie)在嵌入式播放器中提供YouTube的相关信息-意味着“稍后观看”按钮将能够保存视频,而不是提示您的用户从您的页面上移开,返回到YouTube登录后观看再保存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TgQMxGhd-1595833986458)(https://webdev.imgix.net/samesite-cookies-explained/cross-site-cookie-request-header.png)]

网络的文化属性之一就是它往往是默认开放的。这就是为什么很多人可以在那里创建他们自己的内容和应用程序的原因之一。然而,这也带来了一些安全和隐私方面的问题。跨站点请求伪造(CSRF)攻击依赖于这样一个问题:Cookie被附加到给定源的任何请求上,而不管请求的发起者是谁。例如,如果您访问,evil.example 那么它可以触发对 your-blog.example 的请求,并且您的浏览器会很高兴地附加关联的Cookie。如果你的博客不验证并过滤这些请求,那么 evil.example 可能触发删除帖子或添加自己的内容等操作。

用户也越来越意识到如何使用Cookie来跟踪他们跨多个站点的活动。但是,到目前为止,还没有一种方法可以明确地表明您对Cookie的意图。您的 promo_shown Cookie仅应在第一方上下文中发送,而故意嵌入到其他站点的窗口小部件的会话Cookie则有意在第三方上下文中提供登录状态。

# 使用SameSite属性 (明确说明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上引入属性可提供三种不同的方式来控制此行为。您可以选择不指定属性,也可以使用 StrictLax 将Cookie限制为相同站点的请求。

如果设置 SameSiteStrict ,则Cookie仅在第一方上下文中发送。用用户术语来说,只有在Cookie的站点与浏览器的URL栏中当前显示的站点匹配时,才会发送Cookie。因此,如果 promo_shown Cookie设置如下:

Set-Cookie: promo_shown=1; SameSite=Strict

当用户在您的网站上时,该Cookie将与预期的请求一起发送。但是,当您链接到您网站的链接时,例如从另一个网站或通过朋友发送的电子邮件,在该初始请求中,将不会发送Cookie。当您拥有与功能相关的Cookie时,总是处于初始导航之后(例如更改密码或购买商品),但对的限制过于严格,那么这样做会很好 promo_shown。如果您的读者通过链接进入网站,则他们希望发送Cookie,以便可以应用其首选项。

这就是 SameSite=Lax 通过允许这些顶级导航发送Cookie来实现的。让我们从上面重新访问有关cat文章的示例,其中另一个网站引用了您的内容。他们直接利用您的猫照片,并提供指向您原始文章的链接。

<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>

Cookie已设置为:

Set-Cookie: promo_shown=1; SameSite=Lax

当读者在其他人的博客上 时,当浏览器请求时,将不会发送 Cookie amazing-cat.png。但是,当读者点击 cat.html 您博客上的链接时,该请求将包含 Cookie。这 Lax 对于影响网站显示的Cookie来说是一个不错的选择,Strict 并且对于与用户所采取的操作有关的Cookie很有用。

警告:
既不是针对您网站安全的完整解决方案,Strict 也不 Lax 是完整解决方案。Cookies是作为用户请求的一部分发送的,您应该将它们与其他任何用户输入一样对待。这意味着要清理和验证输入。切勿使用Cookie来存储您认为是服务器端机密的数据。

最后,可以选择不指定值,该值以前是隐式声明您希望在所有上下文中发送Cookie的方式。在RFC6265bis的最新草案中, 通过引入新的值明确了这一点 SameSite=None 。这意味着您可以 None 用来清楚地传达您有意要在第三方上下文中发送Cookie的信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XQgLNh4a-1595833986459)(https://webdev.imgix.net/samesite-cookies-explained/samesite-none-lax-strict.png)]
明确标注到Cookie的情况下NoneLaxStrict

如果您提供其他站点使用的服务,例如窗口小部件,嵌入式内容,联属计划,广告或跨多个站点登录,则应使用 None 以确保您的意图明确。

# 更改为不使用SameSite

尽管该 SameSite 属性得到了广泛支持,但不幸的是,它尚未被开发人员广泛采用。开放的默认发送Cookie到处意味着所有用例都可以使用,但使用户容易受到CSRF和意外信息泄漏的影响。为了鼓励开发人员陈述其意图并为用户提供更安全的体验,IETF提案《 渐进式更好的Cookies》 提出了两个关键更改:

  • 没有 SameSite 属性的Cookies 将被视为 SameSite=Lax
  • 的Cookie SameSite=None 也必须指定 Secure,表示它们需要安全的上下文。

Chrome从84版开始实施此默认行为 。Firefox 自Firefox 69起就可以对其进行测试,并将在将来使它们成为默认行为。要在Firefox中测试这些行为,请打开 about:config并设置 network.cookie.sameSite.laxByDefault。 Edge 还计划更改其默认行为。

本文将在其他浏览器宣布支持时进行更新。

# SameSite=Lax

未设置属性
Set-Cookie: promo_shown=1
如果您发送未SameSite指定任何属性的Cookie,则…

应用默认行为
Set-Cookie: promo_shown=1; SameSite=Lax
浏览器将将该Cookie视为SameSite=Lax已指定。

虽然这是为了应用更安全的默认值,但理想情况下,您应该设置一个显式 SameSite 属性,而不要依赖浏览器为您应用该属性。这使您对Cookie的意图明确,并提高了跨浏览器获得一致体验的机会。

警告:
Chrome所采用的默认行为比显式行为要宽松一些,SameSite=Lax 因为它将允许某些Cookie在顶级POST请求中发送。您可以在blink-dev公告中看到确切的详细信息 。这只是暂时的缓解措施,您仍应修复跨站点Cookie才能使用 SameSite=None; Secure

# SameSite=None

拒绝
Set-Cookie: widget_session=abc123; SameSite=None
设置Cookie不设置 Secure 将被拒绝。

公认
Set-Cookie: widget_session=abc123; SameSite=None; Secure
您必须确保 SameSite=NoneSecure 属性配对。

您可以通过启用测试这种行为,因为Chrome浏览器76的 chrome://flags/#cookies-without-same-site-must-be-secure 和从Firefox 69中 about:config 的设置 network.cookie.sameSite.noneRequiresSecure

您将需要在设置新的Cookie时应用此功能,并主动刷新现有的Cookie,即使这些Cookie的有效期限未到。

如果您依靠任何在您的站点上提供第三方内容的服务,则还应与提供商确认他们正在更新其服务。您可能需要更新依赖项或代码片段,以确保您的网站采用新的行为。

这两个更改都与已正确实现该 SameSite 属性的先前版本或者根本不支持该属性的浏览器向后兼容。通过将这些更改应用于Cookie,您可以明确指定其预期用途,而不是依靠浏览器的默认行为。同样,任何 SameSite=None 尚不能识别的客户端都应忽略它,并像未设置属性一样继续操作。

警告:
许多旧版本的浏览器(包括Chrome,Safari和UC浏览器)与新 None 属性不兼容,因此可能会忽略或限制Cookie。此行为在当前版本中已修复,但是您应检查流量以确定受影响的用户比例。您可以在Chromium网站上看到 已知的不兼容客户端列表。

# 食用 SameSite

有关准确更新Cookie的详细信息,以成功处理这些更改 SameSite=None 以及浏览器行为的差异,请浏览原文地址末尾的 SameSite Cookie食谱

# 参考链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值