保护针对CSRF的登录和评论表单

Oni*_*ion 6 php protection login header csrf

我已经阅读了很多关于CSRF保护的文章(这是一个很好的文章)和各种关于SO的问题,但是它们似乎都没有足够的信息来回答我的问题.

我正在开发自己的CMS,我想保护我的登录和评论表单.我将允许匿名用户在我的网站上发表评论.

我网站上的所有表单都使用令牌进行保护.我已经知道这种方法,但问题是它需要一个活动会话(即用户登录后).登录和评论表单的问题在于,几乎任何人都可以访问它们,并且不需要您登录 - 在这种情况下,针对CSRF的最佳保护是什么?

在上面的链接中,我读到当用户尝试登录然后继续使用通常的反CSRF方法(比如将令牌分配给用户的会话)时,可以创建"预会话",但是我对如何实现这一点没有任何见解.

引用者标题是一个弱解决方案,所以我想我不应该打扰.就我测试而言,Origin标题仅在Google Chrome中受支持.自定义标题怎么样?XMLHTTPRequest似乎是一种可能性,但是,我花了三个多小时在谷歌上查找一些关于如何在他们的网站上实施这样的安全措施的信息.但即使我可以使用自定义标头,它是否会使它无用,因为HTTP标头可以完全伪造?

所以,问题是:我应该如何保护我的登录和评论表格免受CSRF的影响?

编辑:以下是我在上面提供的链接中的一些其他信息:

我们建议使用严格的Referer验证来防止登录CSRF,因为登录表单通常通过HTTPS提交,其中Referer标头可靠地存在于合法请求中.如果登录请求缺少Referer标头,则该站点应拒绝防止恶意抑制的请求.

秘密验证令牌可以防御登录CSRF,但开发人员经常忘记实施防御,因为在登录之前,没有会话来绑定CSRF令牌.要使用秘密验证令牌来防止登录CSRF,该站点必须首先创建"presession",实现基于令牌的CSRF保护,然后在成功验证后转换到真实会话.

在阅读上述引文后,我无法结束这一论点.其中一个提到使用referrer标头,但我不确定它是否真的增加了webapp的安全性.

编辑2:使用CAPTCHA怎么样?

eis*_*eis 3

CSRF 问题与某人使用登录的用户凭据提交某些内容有关。这是一个很大的问题,因为恶意网站可以像任何刚刚浏览过您网站的人一样做事。如果您谈论的是可以匿名使用而无需登录的表单,则 CSRF 风险要小得多,因为从其他站点发布到表单的收益要少得多 - 因为任何人都可以使用相同的权限直接执行此操作。

所以我不明白为什么需要针对非登录表单防范 CSRF。

如果您确实想要这样做,会话前令牌在技术上可能与真实会话类似,但只是一种更轻量级的令牌。除了生成的令牌之外,它实际上不会包含任何其他内容。


编辑:关于使用 PHP 提供的 $_SESSION 作为会话前令牌,这是 PHP 的标准会话机制。如果您想使用它,那么是的,仅此而已。

但是,您不会被迫这样做,而且我个人也不会这样做,因为它会消耗所有访问者的服务器内存,而这并不是真正需要的。对于更有效的机制,基本上你需要 a) 一个标识用户的 cookie,b) 存储在服务器端的一些东西,告诉 cookie 是有效的(如果需要,它对谁有效,即 ip)。对于更轻量级的方法,您可以创建一个令牌,将其存储在 cookie 中,并在表单中生成与该令牌匹配的内容作为隐藏字段,并在提交时匹配这些令牌(如 Devesh 所解释的)。后者会阻止从其他站点提交表单,前者甚至会阻止恶意站点在您的站点上进行查找并尝试向最终用户设置任何 cookie 的情况。所以我能想到的三种方法:

  • 只是阻止来自其他站点的图像请求 - 使用 POST 可以防止这种情况
  • 防止从另一个站点提交表单 - 与 cookie 匹配的表单隐藏字段可防止此情况发生
  • 防止从在您的网站上进行预查找的另一个网站提交表单 - 这需要 IP 验证,存储在服务器端的内容,例如数据库中与 cookie 匹配的 IP

EDIT2:在验证码上,它们的主要用例是防止自动(暴力)登录尝试。他们也会解决登录表单上的 CSRF 请求问题,但这样做有点过分了。为了防止暴力登录攻击,在某些情况下可能需要它们,尽管可能需要更用户友好的东西,以免过多降低可用性。也许像KittenAuth之类的东西:)