项目背景
需求是一个类似 Disqus 的用户评论系统,用户评论模块使用 Iframe 嵌入到其他网站;但是用户属于公共的用户系统,所以使用单点登录,需要用到登录系统生成的 Cookie。
问题及探究
用户评论模块通过 Cookie 调取用户信息时,控制台提示:
this set-cookie didnot specify a "sameSite" attribute and was defaulted to "sameSite=Lax" and broke the same rules specified in the SameSiteLax value
出现这个问题的原因是从 Chrome 51 开始, 为了防止 CSRF 攻击,Cookie 新增加了一个 SameSite
属性,用来禁止第三方 Cookie 的读写权限,并且在最新版本 Chrome 中,该功能无法从设置中关闭。
SameSite
属性可以有3个值:
Strict
:完全禁止第三方 Cookie ,跨站点时,任何情况下都不会发送 Cookie 。Lax
:大多数情况也是不发送第三方 Cookie ,GET 请求除外。None
:关闭SameSite
属性,但前提是必须同时设置Secure
属性( Cookie 只能通过 HTTPS 协议发送),否则无效。
所以说,可以通过设置 Set-Cookie: cookie_data=abc123; SameSite=None; Secure
来解决这个问题;或者,既然这个问题出在 Cookie 上,那么也可以不使用 Cookie ,通过后端定义 token 来解决这个问题(推荐),因为 token 不会自动被浏览器携带。
什么是 CSRF ?
CSRF ( Cross-site request forgery ) 跨站请求伪造:攻击者引诱受害者进入第三方网站,利用受害者的 Cookie ,冒充受害者进行某些操作。具体攻击流程大概如此:
- 受害者正常登录网站 a ,获取了 a 的凭证 Cookie
- 攻击者引诱受害者访问网站 b
- 网站 b 向网站 a 发送请求,由于之前受害者访问了网站 a ,所以这个攻击请求利用之前的 Cookie 绕过了后台的用户认证
- 以受害者的名义,执行一些操作
- 攻击完成。