似乎 CSRF 保护属性“SameSite=Strict”并未在所有情况下都提供所需的保护。
场景1(作品):
- 用户登录
https://example.com
。会话 cookie 已设置,受“SameSite=Strict”保护。 - 用户访问
https://attack-1abc2def.com
。跨域表单 POSThttps://example.com/foo
不会发送会话 cookie,很好,保护工作。
方案 2(已损坏):
https://example.com
如上所述登录。设置了会话 cookie:
Set-cookie: PHPSESSID=1234; path=/; domain=.example.com; secure; HttpOnly; SameSite=Strict
- 用户访问
https://attack-1abc2def.com
。该网站制作了一个跨域表单 POST 到https://example.com/login
. 会话 cookie 不会一起发送,因为使用SameSite=Strict
.
但是:/login
路由设置了一个新的会话 cookie
Set-cookie: PHPSESSID=9876; path=/; domain=.example.com; secure; HttpOnly; SameSite=Strict
。(一些框架,比如 Symfony,为每个登录请求设置一个新的会话 cookie,无论是否成功。)
这个 cookie 被存储,因此替换了有效的会话 cookie - 尽管有SameSite
标志。
-> 即使之前的会话仍然有效,浏览器不再使用它,因此用户实际上已注销。
我在 Chrome/78.0.3904.108 和 Firefox/70.0 中对此进行了测试。CSRF 保护适用于场景 1,因为我添加了“SameSite=Strict”标志,但在场景 2 中有描述的问题。
“SameSite”cookie 规范(或浏览器开发人员)是否可能错过了场景 2?
我希望“SameSite”标志不再需要特殊的 CSRF 保护措施。
恕我直言,“SameSite”标志不仅应该防止发送现有的 cookie,还应该防止存储新的 cookie。