suukii / fe-interview

前端面试题整理
5 stars 0 forks source link

SameSite Cookie #36

Open suukii opened 4 years ago

suukii commented 4 years ago

一个 cookie 除了 key=value 对以外,还有一系列可选属性可以设置,这些属性用来控制 cookie 的使用场景,比如 Max-Age 指定 cookie 的过期时间,Secure 指定 cookie 只能用于 https 请求。服务器通过 Set-Cookie 响应头部在浏览器中设置 cookie。

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

曾经的 cookie

浏览器在发送请求时,会带上同域名下设置的所有 cookie,不管是谁发起的请求,这会导致两个问题:

  1. 可能会导致性能问题,如果一个网站的 cookie 设置过多,可能会延长请求发送的时间。要避免这个问题,需要合理地设置 cookie,比如设置合适的过期时间,不要让 cookie 的存活时间不必要的长。

  2. 可能会导致安全问题。假设你在浏览器中打开了 A.com 并登录,登录成功后 A.com 在你的浏览器中设置了一个 cookie sessionid 来保存登陆状态,紧接着你打开了 B.com,B.com 上有一张图片 A.com/img.png,于是浏览器发送请求去获取这张图片,由于域名相同,这个请求会带上 A.com 中设置的 sessionid 这个 cookie,这就是 CSRF 攻击。

第三方请求携带 cookie 这个行为也不一定是不好的。比如你在网站 A 中看到了一个 B 站的嵌入视频,你点了“稍后再看”,如果此时你在另一个标签页登录了 B 站,你点击“稍后再看”按钮向 B 站发起的这个请求就会带上 B 站登录状态的 cookie,网站 A 也就不用再要求你先登录 B 站了。

SameSite cookie

SameSite 属性出现后,我们就可以通过它来控制 cookie 是否可以被第三方(跨站)请求携带了,设置方式如下:

Set-Cookie: promo_shown=1; SameSite=Strict

可以设置的值:

  1. Strict:表示跨站网站发起的请求不能携带这个 cookie
  2. Lax
  3. None:跟以前一样,本站和跨站的请求都会带上这个 cookie

如果不设置这个属性,以前的默认行为是 SameSite=None,现在:

chrome 80 已经实现了这两个默认行为,其他现代浏览器也在实现中。

实际上显式设置 SameSite=Lax 和不设置 SameSite 属性还是有轻微不同的。learn more

warning: SameSite=None 属性是后来加的,有些浏览器版本可能会不支持。