我在我的网站上的每个发布方法上都实现了 CSRF 令牌。但是当我在不同的选项卡中访问我的网页时,令牌在页面和令牌不匹配上都会发生变化。我的令牌存储在 DOM 中,我正在使用 SESSION 匹配令牌。如何解决这个问题。?
5 回答
我在每个成功的请求上更改令牌
是的,这就是为什么我们不会在每次成功请求时使令牌失效。这不仅会破坏多标签浏览,还意味着您不能执行诸如点击后退按钮然后提交之类的操作。
“在每个请求上使令牌无效”是您从测试报告中获得的一种虚假安全建议,测试人员没有发现太多真正易受攻击的内容。无论您是否这样做,这都是一个权衡,但可用性的缺点几乎总是超过最小的安全优势。
您只需要在特权级别更改时使 CSRF 令牌(连同会话令牌)失效,尤其是在登录时。这通过防止在登录之前知道会话和 CSRF 令牌的攻击者在您登录后利用这些令牌来减轻会话固定攻击。
请发布示例代码,除非您使用的是 ajax(我不建议 CSRF 令牌使用,如果您打开一个新选项卡,代码不应在两个选项卡中更改)。另外,我不同意 bobince,您正在做正确的事情来实施此措施,因为一旦您有了适当的逻辑,您就可以轻松轻松地在所有形式中使用它。实现这一点的最佳方法是让每个令牌在一定时间后过期。
bobince:CSRF 令牌用于防止 CSRF 攻击而不是会话固定攻击,两者不同,前者防止脚本代表用户执行操作,而后者是恶意用户通过猜测或窃取他们的行为来冒充普通用户的攻击会话 ID。
您可以轻松实现这一点:
在服务器端,将 CSRF 令牌存储在会话中,如下所示:
$_SESSION['csrf_tokens']['form1'] = //code to generate csrf token
在表单提交上验证令牌时,您可以检查,
$_SESSION['csrf_tokens']['form1'] === $_POST['csrf_token']
生成两个值——一个随机密钥(fe 通过 uniqid)和一个随机令牌。
每次呈现表单时都会生成两者 - 并将它们都放入隐藏字段中。然后使用随机密钥将令牌保存到会话中。然后当收到表单数据时,检查令牌发送是否在密钥发送下的会话中。(如果是这样,您当然可以在处理完表单后使用此键删除条目。)
其他任何事情(令牌的到期时间、令牌与某种表单类型的绑定)都与以前相同。
像这样不必要且不安全,为什么您不使用 openssl_random_pseudo_bytes() 基于会话创建令牌,这将产生一个安全令牌,并检查是否正确,或者您也可以在 2-5 分钟后使用过期。您也可以在 owasp 上查看 dom 上的令牌,很容易被喷!!!