yaofly2012 / note

Personal blog
https://github.com/yaofly2012/note/issues
44 stars 5 forks source link

Cookie SameSite=None #162

Open yaofly2012 opened 4 years ago

yaofly2012 commented 4 years ago

一、背景

突然本地启动的应用通过公司SSO登录后依旧拿不到登录态信息。排查发现保存登录态的cookie增加了Secure属性:

set-cookie: ticket=86A24; Max-Age=7775999; Domain=test.com; Path=/;HttpOnly; SameSite=None; Secure

咦?平台团队怎么突然加了Secure属性,并且SameSite=None;又是啥?

二、Cookie的SameSite属性是啥?

2.1 先弄清几个概念

1. 同站(Same Site)和跨站(Cross Site)

同站: 顶级域名+1相同(即主域相同)的站点(跟端口无关),也叫本方(First-party); 跨站:非同站,也叫第三方(Third-party)。

2. 同源(同域)(Same Origin)和跨域(Cross Origin)

同源:协议(https?)+域名+端口 三者完全相同; 跨域:非同源。

3. 跨站请求

首先要明白一个页面引用的外部资源(CSS,JS,图片以及通过JS API发送的请求等)可能来自不同的站点。 跟页面不是同站的请求都是跨站请求。 如页面www.example.com/a里引用了图片www.baidu.com/image/dog.png,加载图片的请求就是跨站请求。

跨站请求概念是相对的,如图片www.baidu.com/image/dog.png在页面www.example.com/a里是跨站请求,但是在www.baidu.com/a页面里是同站请求。

2.2 干什么?

SameSite属性就是控制哪些跨站请求可以携带cookie。

  1. 解决跨站cookie信息泄露;
  2. 防御CSRF攻击

2.3 语法

三种取值

1. Strict

严格模式,必须同站请求才携带cookie。 如用户访问的页面www.example.com/a里引用了图片www.baidu.com/image/dog.png

  1. 图片请求不会携带SameSite=Strict的cookie;
  2. 图片响应SameSite=Strictset-cookie会被拒绝 image

2. Lax (relax缩写)

这是浏览器中的默认值。 Cookies允许与顶级导航一起发送,并将与第三方网站发起的GET请求一起发送,其他情况则同Strict

3. None

显示的禁止SameSite限制,必须配合Secure(即要使用HTTPS)一起使用(浏览器最后的坚持)。

顶级导航&GET请求

比较难理解的就是"顶级导航",比如:

2.4 怎么用?

首先看cookie怎么用的:

  1. 对于只需要同站访问的cookie可以显示的指定SameSite=Lax/SameSite=Strict;
  2. 对于跨站访问的cookie需要显示的指定SameSite=None; Secure
  3. 不要采用SameSite默认,跨浏览器的默认行为不一致。 Chrome可以控制

三、跟CSRF(Cross Site Request Forgery)啥关系?

解决CSRF问题的一种方案。

四、再看文档开头提到的问题:

登录态cookie需要被跨站访问,所以平台把登录态cookie设置成SameSite=None; Secure。因为本地开发时启动的应用是http协议的,所以无法拿到登录态cookie。

4.1 解决方案

  1. 在DevTool里手动把登录态Cookie的Secure属性删掉。

参考

  1. 掘金:预测最近面试会考 Cookie 的 SameSite 属性
  2. SameSite Cookie,防止 CSRF 攻击
  3. web_dev: SameSite cookies explained
  4. Medium: SameSite Cookie attribute?
  5. SameSite examples
  6. Understanding "same-site" and "same-origin"
yaofly2012 commented 2 years ago

遇到的问题

image

SameSite=Lax使用限制

Chrome报错错误: image image

详情~戳~

SameSite=None必须Secure一起使用

FireFox提示: image

参考

  1. MDN Set-Cookie
  2. Schemeful Same-Site