我读过很多关于CSRF保护的文章(这个不错 http://seclab.stanford.edu/websec/csrf/csrf.pdf)以及关于SO的各种问题,但它们似乎都没有足够的信息来回答我的问题。
我正在开发自己的 CMS,我想保护我的登录和评论表单。我将允许匿名用户在我的网站上发表评论。
我网站上的所有表单均使用令牌进行保护。我已经知道这种方法,但问题是它需要一个活动会话(即用户登录后)。登录和评论表单的问题在于,几乎任何人都可以访问它们,并且不需要您登录 - 在这种情况下,针对 CSRF 的最佳保护是什么?
在上面的链接中,我读到当用户尝试登录时可以创建一个“预会话”,然后继续使用通常的反 CSRF 方法(例如为用户的会话分配令牌),但我不知道如何实现这一目标。
引用头是一个弱解决方案,所以我想我不应该打扰。据我测试,Origin 标头仅在 Google Chrome 中受支持。自定义标头怎么样? XMLHTTPRequest 似乎是一种可能性,但是,我实际上花了三个多小时在 Google 上查找一些有关如何在其网站上实施此类安全措施的信息。但即使我可以使用自定义标头,由于 HTTP 标头可以完全伪造,因此它是否会变得毫无用处?
那么问题来了:我应该如何保护我的登录和评论表单免受 CSRF 的影响?
Edit:以下是我上面提供的链接中的一些附加信息:
我们建议严格的 Referer 验证以防止登录 CSRF
因为登录表单通常通过 HTTPS 提交,其中 Referer
对于合法请求,标头可靠地存在。如果有登录请求
缺少Referer header,网站应拒绝防御请求
反对恶意打压。
and
秘密验证令牌可以防御登录CSRF,但开发者
经常忘记实施防御,因为在登录之前,有
没有要绑定 CSRF 令牌的会话。使用秘密验证
为了防止登录 CSRF,站点必须首先创建一个
“presession”,实现基于token的CSRF保护,然后
身份验证成功后转换到真实会话。
读完上面的引文后,我无法结束这个争论。其中之一提到使用引用标头,但我不太确定它是否真的大大提高了网络应用程序的安全性。
Edit 2:使用验证码怎么样?
CSRF 问题与某人使用登录的用户凭据提交某些内容有关。这是一个很大的问题,因为恶意网站可以像任何刚刚浏览过您网站的人一样做事。如果您谈论的是可以匿名使用而无需登录的表单,则 CSRF 风险要小得多,因为从其他站点发布到表单的收益要少得多 - 因为任何人都可以使用相同的权限直接执行此操作。
所以我不明白为什么需要针对非登录表单防范 CSRF。
如果您确实想要这样做,会话前令牌在技术上可能与真实会话类似,但只是一种更轻量级的令牌。除了生成的令牌之外,它实际上不会包含任何其他内容。
编辑:关于使用 PHP 提供的 $_SESSION 作为会话前令牌,这是 PHP 的标准会话机制。如果您想使用它,那么是的,仅此而已。
但是,您不会被迫这样做,而且我个人也不会这样做,因为它会消耗所有访问者的服务器内存,而这并不是真正需要的。对于更有效的机制,基本上你需要 a) 一个标识用户的 cookie,b) 存储在服务器端的一些东西,告诉 cookie 是有效的(如果需要,它对谁有效,即 ip)。对于更轻量级的方法,您可以创建一个令牌,将其存储在 cookie 中,并在表单中生成与该令牌匹配的内容作为隐藏字段,并在提交时匹配这些令牌(如 Devesh 所解释的)。后者会阻止从其他站点提交表单,前者甚至会阻止恶意站点在您的站点上进行查找并尝试向最终用户设置任何 cookie 的情况。所以我能想到的三种方法:
- 只是阻止来自其他站点的图像请求 - 使用 POST 可以防止这种情况
- 防止从另一个站点提交表单 - 与 cookie 匹配的表单隐藏字段可防止此情况发生
- 防止从在您的网站上进行预查找的另一个网站提交表单 - 这需要 IP 验证,存储在服务器端的内容,例如数据库中与 cookie 匹配的 IP
EDIT2:在验证码上,它们的主要用例是防止自动(暴力)登录尝试。他们也会解决登录表单上的 CSRF 请求问题,但这样做有点过分了。为了防止暴力登录攻击,在某些情况下可能需要它们,尽管可能需要更用户友好的东西,以免过多降低可用性。也许像小猫认证 http://thepcspy.com/kittenauth/ :)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)