问题描述
据我了解,当在服务器端启用CSRF时,服务器会创建一个令牌(例如token1)并将其注入到form
中,并将其保存在客户端浏览器的cookie中。
客户端向服务器发送form
请求时,它会从浏览器cookie中发送csrf令牌(token1),并发送与form
中相同的令牌。服务器通过检查cookie中的令牌和form
中的令牌是否匹配来验证请求,然后处理该请求。
现在,如果我在另一个选项卡中打开相同的form
,服务器将生成另一个令牌(token2)并将其注入到form
和cookie中。然后,在Cookie中,token1
将被token2
覆盖。因此,在这种情况下无法在第一个标签中提交表单?但是从经验来看,我发现选项卡1中的form
提交仍然成功。
那么有人可以解释一下在上述情况下它是如何成功的吗?
解决方法
既然您已经添加了Spring Security标记,我将描述Spring Security如何使用同步器令牌模式来防御CSRF攻击。
服务器创建一个令牌(例如token1)并将其注入表单,并将其保存在客户端浏览器的cookie中。
这不完全是什么情况。服务器将创建一个CSRF令牌(token1)并将该令牌存储在HttpSession中。 CSRF令牌(token1)也以客户端形式嵌入。还会为客户端提供存储在Cookie中的会话ID(session-id1)。
当客户端提交表单时,它将发送令牌1和会话ID1。然后,服务器将使用session-id1查找HttpSession并获取该会话的预期CSRF令牌。它将预期的CSRF令牌与token1进行比较,如果值不匹配,则HTTP请求将被拒绝。
如果在另一个选项卡中打开相同的表单,浏览器仍然可以访问会话ID(session-id1)。该表单将获得与session-id1关联的相同令牌(token1)。
最后,两个选项卡中仅使用一个CSRF令牌(令牌1)。
您可以在Spring Security reference documentation中找到有关防御CSRF攻击的更多信息。