是否应该保护登录表单免受 CSRF 的影响?

Ces*_*vas 3 python csrf flask python-3.x flask-login

我已经阅读了很多有关 CSRF 保护的内容,但是我有一个疑问,我无法澄清,甚至在 stackoverflow 中也无法澄清。

因此,我正在使用 Flask 构建一个 Web 应用程序,并且有一个名为 csrf_token 的函数,您可以调用该函数来生成令牌并将其放入表单(在本例中为登录表单)作为隐藏输入。但是,我在想,如果攻击者进入登录站点来获取他的 csrf 令牌,这是否会破坏该站点上的 csrf 保护?因为这样他就可以将他的 csrf 令牌附加到 ajax 请求中,这基本上等于没有任何保护。

Mar*_*ers 6

您误解了 CSRF 的工作原理。

不,攻击者不能直接获取任何 CSRF 令牌。发送给不同用户的CSRF令牌是不同的。获取现有的 CSRF 令牌,然后使用它来尝试使用该不同的令牌欺骗不同的用户将会失败,因为该令牌与用户访问表单时所使用的浏览器已提供的令牌不匹配。

不仅令牌会有所不同,CSRF 令牌的要点还在于它会两次提供给用户,而攻击者无法访问这两个值。CSRF 令牌既存储在 cookie 中(最好HttpOnly设置为 True,这样浏览器中运行的代码甚至无法访问它),又嵌入到表单中。提交表单时,随表单发布的令牌必须与 cookie 中的令牌匹配。

因此,攻击者不仅无法使用早期的 CSRF 令牌(这与用户获得的令牌不同),而且攻击者也不知道浏览器会向用户发送什么 cookie,也无法访问该 cookie即使HttpOnly设置,因为域 A 上的攻击者无法读取域 B 的 cookie。

假设您在这里使用Flask-WTF CSRF 保护(给出函数名称)。该包将 CSRF 令牌存储在 Flask 会话中,并以加密方式对令牌进行签名并附加超时,因此攻击者也无法用包含自己令牌的另一个会话替换该会话。此外,如果您的用户通过 HTTPS 访问站点,则 HTTP Referer 标头必须与客户端访问的主机名匹配。

至于登录表单是否需要使用 CSRF 进行保护的问题:是的,因为如果攻击者可以选择受害者使用的登录名,那么他们就可以访问受害者进入网站的任何其他内容。通过保护您的登录表单免受 CSRF 攻击,您可以保护您的用户免受这种情况的影响。


有趣的是,我在 2000 年 5 月向当时还很新的 Mozilla 项目报告了这个问题,在开源 Zope 平台上发现了这个问题后,讨论了浏览器如何帮助缓解现在所谓的 CSRF 问题。男孩,这让我现在感觉自己老了。