参考文档

https://www.jianshu.com/p/4f3579774a28

https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html

SameSite场景

跨页面发送cookie是一个常见的需求,但是如果你的后端允许跨域携带Cookie,就有可能被CSRF攻击。

如果想同站的页面发送请求时候携带cookie,跨站的不携带cookie,应该怎么办呢?

chrome和一些浏览器支持了这种能力。

先说明一下什么是同站(SameSite)

同站和同源

同站和同源不一样,同站判断就比较宽松:只要两个 URL 的 eTLD+1 相同即可,不需要考虑协议和端口。其中,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1 则表示,有效顶级域名+二级域名,例如 baidu.com 等。

举几个例子,www.taobao.com 和 www.baidu.com 是跨站,a.baidu.com 和 b.baidu.com是同站,a.github.io 和 b.github.io 是跨站(注意是跨站)。

SameSite规则

后端在set-cookie里面指定SameSite属性,以此来控制三方网站携带cookie的策略。若未指定,Chrome最新版本默认取值是”lax”。

SameSite属性可取值为

  • Strict
  • Lax
  • None

Strict

Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

Lax

Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

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

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

请求类型 示例 正常情况 Lax
链接 发送 Cookie 发送 Cookie
预加载 发送 Cookie 发送 Cookie
GET 表单
发送 Cookie 发送 Cookie
POST 表单 发送 Cookie 不发送
iframe 发送 Cookie 不发送
AJAX $.get(“…”) 发送 Cookie 不发送
Image Cookie的SameSite属性 - 图1 发送 Cookie 不发送

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

None

若想允许非同站访问接口时候携带cookie,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。