Cookies的SameSite属性

自Chrome 51版本开始,浏览器的 Cookies 新增了一个SameSite属性,用来防止 CSRF 攻击和信息泄漏,更多信息参考chrome Feature: 'SameSite' cookie attribute

Cookies的SameSite属性

简单回顾什么是CSRF攻击

Cookies往往用来存储用户的身份信息,恶意网站通过设法伪造带有正确Cookies进行 HTTP 请求,这就是 CSRF 攻击。

举例来说,用户登陆了银行网站your-bank.com,银行服务器发来了一个 Cookie。

Set-Cookie: session_id=abc123;

用户后来又访问了恶意网站malicious-site.com,恶意网站总是想方设法让你在恶意站点发送一个表单请求。

手段:中奖填写联系信息、透明的form表单提交按钮、附加在诱惑图片上的超链接

<form action="your-bank.com/transfer" method="POST">
  ...
</form>

用户一旦被诱骗发送这个表单,银行网站就会收到带有正确 Cookie 的请求。为了防止CSRF攻击,银行网站表单会设置一个隐藏域,表单提交时一起带上一个随机token至服务器,告诉服务器这是真实请求。

<form action="your-bank.com/transfer" method="POST">
  <input type="hidden" name="token" value="dad3weg34">
  ...
</form>

之所以被CSRF攻击,是因为恶意网站诱导你在其页面上发送了第三方cookie(此时的银行网站cookie为第三方cookie),它除了用于 CSRF 攻击,还可以用于用户追踪。

第三方是一种相对概念,规定假定你正在访问的站点为第一方站点,则浏览器为第二方,其他网站就是第三方站点,第三方站点诱导你发送第一方站点的cookie时,我们就说此时的cookie为第三方cookie。

比如,Facebook 在第三方网站插入一张看不见的图片。

<img src="facebook.com" style="visibility:hidden;">

浏览器加载上面代码时,就会向 Facebook 发出带有 Cookie 的请求,从而 Facebook 就会知道你是谁,访问了什么网站。

SameSite

cookies机制一直被认为是不安全的,随着技术的更新,界内一直在完善cookies的安全机制,SameSite属性是谷歌浏览器为完善cookies安全机制出的特性之一。

Cookie 的SameSite属性用来限制第三方 Cookie的行为。

它可以设置三个值。

  • Strict
  • Lax
  • None

Strict

Strict最为严格,完全禁止第三方 Cookie,当当前站点与请求目标站点是跨站关系时,总是不会发送 Cookie。换言之,只有当前站点 与请求目标站点是同站关系时,才会带上 Cookie。

Set-Cookie: CookieName=CookieValue; SameSite=Strict;

这个规则过于严格,可能造成非常不好的用户体验。

举例说明:

假定你当前所处站点地址为https://obmq.com/index.html,该站需要通过XHR请求获取某天气站点的未来7天的天气信息https://weather-forecast.org/api/weather?future=7,该接口要求必须携带cookieSet-Cookie: vip=true; Path=/; HttpOnly; SameSite=Strict;,这种情况下,你无论如何都无法在https://obmq.com站点下发送这个XHR请求时还能携带上这个cookie,换句话说,你发送的接口请求的cookie请求头一定不会有vip=true,即使你现在已经是该天气网站的vip。

None

None在Chrome 85 版本之前是SameSite的默认设置值,即Set-Cookie: key=value; SameSite=None等于Set-Cookie: key=value

在Chrome 85 版本之前,显示设置SameSite=None不需要设置Secure属性,详细参见:Reject insecure SameSite=None cookies

在Chrome 85 版本以后,站点选择显式关闭SameSite属性时,在将其值设为None的同时。必须同时设置Secure属性(表示Cookie 只能通过 HTTPS 协议发送),否则无效。

下面的设置有效。

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

Cookies的SameSite属性

下面的设置无效。

Set-Cookie: widget_session=abc123; SameSite=None

Cookies的SameSite属性

Lax

Chrome 在85版本后将Lax设为SameSite的默认值,即Set-Cookie: key=value; SameSite=Lax等于Set-Cookie: key=value,详细参见:Cookies default to SameSite=Lax

Lax规则比较宽松,大多数情况也不发送第三方 Cookie,但是导航到目标站点的 Get 请求除外。

Set-Cookie: CookieName=CookieValue; SameSite=Lax;

导航到目标站点的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。

请求类型 示例 SameSite=None;Secure 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 不发送
xhr/fetch $.get("...") 发送 Cookie 不发送
Image <img src="..."> 发送 Cookie 不发送
Script <script src="..."> 发送Cookie 不发送

设置了StrictLax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

Schemeful Same-Site

自Chrome 86版本开始,考虑到不安全的http://协议仍然为网络攻击者提供了篡改cookie的机会,然后将这些cookie用于站点安全的https://。谷歌浏览器修改了cookie的Same Site的定义,将在相同域名的安全(https://)协议和不安全(http://)协议作为是否跨站的判断因素之一。详情参见Feature: Schemeful same-site

如果您的站点全面升级到https协议,那么下面的内容不适合您;如果您的站点是https协议和http协议混存,那么您需要关注。

常见的 "cross-scheme" Cookies携带情况

超链接

Schemeful Same-Site禁止时,从http:// site.example链接到https

上一篇:selenium的入门使用


下一篇:C#(winform)项目中自制alert提示窗体并引用系统图标资源