对 CSRF 保护策略感到困惑

Posted

技术标签:

【中文标题】对 CSRF 保护策略感到困惑【英文标题】:Confusing about CSRF protection strategies 【发布时间】:2019-05-09 10:00:35 【问题描述】:

我正在测试一个 Web 应用程序。 CSRF 在 cookie 和 header 中应用和发送,但不以隐藏输入的形式发送。 csrf 令牌不会因每个请求而更改,但会在会话期间更改。 csrf 令牌应该多久更改一次?它应该在每个会话或每个请求中更改吗?客户端或服务器应该设置 csrf 令牌吗?应用 csrf 保护的最佳策略是什么?双重提交cookie?三重提交 Cookie ?或任何其他新策略?

【问题讨论】:

【参考方案1】:

我只是试着在这里一一回答你的问题。

CSRF 令牌应该多久更换一次?

您可以在每个会话中更改一次 CSRF 令牌。每个请求更改一次并没有提供真正的安全优势,如果有的话,只能作为一种浪费资源和限制可用性的简单方法。例如,用户将无法点击“返回”按钮,因为他们将拥有一个过时的 CSRF 令牌,或者如果他们尝试重新提交具有新值的表单(例如在验证错误之后),它可能不会发送。

应该在每个会话或每个请求中更改吗?

如前所述,它应该在每个会话中更改。用户每次请求都应该获得一个新令牌的唯一时间是在登录时。这是为了防止会话固定攻击导致 CSRF 攻击的可能性。

例如: 攻击者访问该站点并生成一个新会话。他们获取会话 ID 并将其注入受害者的浏览器(例如,通过从易受攻击的邻居域写入 cookie,或使用 jsessionid URL 等其他漏洞),并将 CSRF 令牌注入受害者浏览器的表单中。他们等待受害者使用该表单登录,然后使用另一个表单帖子让受害者使用仍然有效的 CSRF 令牌执行操作。

为防止这种情况,请使 CSRF 令牌无效并在您已经对会话 ID 执行相同操作的位置(如登录)发出一个新令牌,以防止会话固定攻击。

客户端或服务器应该设置 CSRF 令牌吗?

服务器 - 始终在服务器上!您希望根据 OWASP 指南从受信任的来源生成令牌。这可确保您准确了解令牌的生成位置并限制攻击面,因为攻击者无法控制服务器上发生的事情。

应用 CSRF 保护的最佳策略是什么?

我认为 CSRF 是一个非常有深度的话题,不能用几句话来概括。这是一点研究和阅读可以大有帮助的地方。我建议你看看OWASP CSRF Prevention Cheat Sheet。

【讨论】:

使用双重提交,可以在现代浏览器的客户端上生成令牌(使用Crypto.getRandomValues())。双重提交(尤其是客户端令牌生成)的风险略高,但对于许多应用程序来说仍然可以接受,并且在某些情况下可能更容易。 感谢 Horkrine 的详细回答,剩下一点,我的应用程序中的 csrf 令牌没有作为表单中的隐藏输入提交,它作为 cookie 作为标头发送,是被认为是风险?顺便说一句,该应用程序正在使用 ssl 和 HSTS 策略 正如我在 owasp 建议中看到的那样,csrf 令牌应该作为表单中的隐藏元素发送,我在许多 java csrf 保护实现中也看到了...... 嗨,汤姆。我一直将我的 CSRF 令牌作为隐藏元素放置在表单中——我从未将它们放在 cookie / header 中,因此我无法提供可靠的答案。不过,我找到了this answer,可能对你有用 感谢 Horkrine,从您发送的链接中,我看不出在请求正文(作为隐藏表单字段)或作为 cookie 或作为标头发送 csrf 令牌之间存在安全差异。 .. 那么为什么 owasp 建议将其作为隐藏表单字段发送?可能是因为使用 ssl 时 cookie 和 header 参数比消息体更容易访问?

以上是关于对 CSRF 保护策略感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

在 Python REST API 中实现 CSRF 保护

如果没有同源策略,一个邪恶的网站可以读取 CSRF 令牌吗?

我的 CSRF 保护方法安全吗?

web安全之同源策略

策略和状态模式之间的简化区别

使用 MagicalRecord 在后台保存的设计策略