似乎CSRF保护属性“ SameSite = Strict”在所有情况下均未提供所需的保护。
方案1(可行):
https://example.com
。已设置会话cookie,并使用“ SameSite = Strict”进行保护。https://attack-1abc2def.com
。跨域格式POST到https://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
。该网站将跨域表单发布到https://example.com/login
。由于受SameSite=Strict
保护,因此不会发送会话cookie。但是:/login
路由设置了一个新的会话cookieSet-cookie: PHPSESSID=9876; path=/; domain=.example.com; secure; HttpOnly; SameSite=Strict
。 (某些框架,例如Symfony,无论成功与否,都会为每个登录请求设置一个新的会话cookie。)尽管SameSite
标志,但已存储此cookie,因此将替换有效的会话cookie。->即使先前的会话仍然有效,浏览器也不再使用它,因此用户已被有效注销。我在Chrome / 78.0.3904.108和Firefox / 70.0中对此进行了测试。自从我添加了“ SameSite = Strict”标志以来,CSRF保护在方案1中就可以正常工作,但是在方案2中存在描述的问题。
“ SameSite” cookie规范(或浏览器开发人员)是否错过了方案2?我希望不再需要带有“ SameSite”标志的特殊CSRF保护措施。
恕我直言,“ SameSite”标志不仅应防止发送现有的cookie,还应防止存储新的cookie。
这是预期的行为。所有顶级请求都可以设置SameSite cookie。这反映在规范的最新版本中:https://github.com/httpwg/http-extensions/pull/800
从SameSite cookies explained引用:
仅当cookie的站点与浏览器的URL栏中当前显示的站点匹配时,才会发送cookie。
这意味着SameSite=Strict
或SameSite=Lax
将充当跨站点通信的保护机制仅用于第一步,即当用户首次单击从一个站点到另一个站点的链接时。由于URL来源相同,因此以下导航将使用cookie。