停止在身份验证时重新生成/使 CSRF 无效

Posted

技术标签:

【中文标题】停止在身份验证时重新生成/使 CSRF 无效【英文标题】:Stop regenerating/invalidating CSRF on authentication 【发布时间】:2013-08-11 10:39:41 【问题描述】:

我的页面上目前有表单,无论用户是否登录,这些表单都在那里。用户登录后,会看到其中一种表单(使用 CSRF)。

问题是,如果在身份验证后显示此框,则 CSRF 令牌无效。我已经通过允许自己在没有身份验证检查的情况下提交表单来确认这一点,$form->isValid() 返回true 而登录后,它给了我false 错误:

CSRF 令牌无效。请尝试重新提交表单。

我想有三种解决方案 - 阻止 Symfony 在身份验证时重新生成/使 CSRF 令牌无效,从这些表单中删除 CSRF 令牌或在身份验证后生成我的表单(但是我宁愿避免这种情况)。我目前的解决方案是通过身份验证传回一个新的 CSRF 令牌并设置表单令牌 input 值。

附加:有人知道如何查看当前分配的所有 CSRF 令牌吗?会议似乎没有举行他们。

【问题讨论】:

登录后页面没有重新加载? @Hisamu 不,登录是使用 ajax 完成的,所以用户登录,然后我在成功登录时打开一个表单。这是令牌失效的地方(似乎)。如果我知道在哪里查看所有令牌,我将能够进一步调试它。 也许您可以重新生成其他令牌?见:***.com/a/11632713/209585 @Hisamu,我曾考虑过这一点,但考虑到我最终会使用的表单数量,我宁愿让 symfony 不会使 csrf 令牌无效!但如果我不能,我想我将不得不走另一条路。 如果您在登录时不重新生成 CSRF,您可能会容易受到固定攻击:攻击者创建一个会话,保存 CSRF 密钥,通过 cookie 强制用户进入该会话,等待用户登录,然后可以发送带有有效 CSRF 令牌的伪造请求。 【参考方案1】:

通常的方法是,当有人成功登录时,整个页面都会刷新,因为可能会显示不同的数据,为用户定制。

但是,如果你真的不想那样做,你说:

我目前的解决方案是通过身份验证传回一个新的 CSRF 令牌并设置表单令牌输入值。

就这么做吧。这没有什么不妥。

【讨论】:

【参考方案2】:

感谢@MarkFox 将我指向this CWE - 虽然我知道这是通过设计,但我希望有办法让我避免走上我最终选择的路线。

对于任何感兴趣的人,CWE 声明:

在不使任何现有会话标识符失效的情况下对用户进行身份验证或以其他方式建立新的用户会话,使攻击者有机会窃取经过身份验证的会话。

因此,我建议您按照我最终选择的方式发送新的request tokens via AJAX 并将它们放入相关表格中。

【讨论】:

以上是关于停止在身份验证时重新生成/使 CSRF 无效的主要内容,如果未能解决你的问题,请参考以下文章

Symfony:身份验证请求失败:无效的 CSRF 令牌

CSRF 保护

Laravel CSRF 保护

Jmeter 身份验证令牌

如何使 ASP.NET Core 中的身份验证 cookie 无效?

Laravel 和 Vue 身份验证表单在登录失败时重新加载