我有一个网站,人们可以这样投票:

http://mysite.com/vote/25

这将对项目 25 进行投票。我只想让注册用户可以使用此功能,并且仅当他们想要这样做时才可用。现在我知道当有人在网站上忙碌时,有人给他们一个像这样的链接:

http://mysite.com/vote/30

那么他就可以对该项目进行投票,而他并不想这样做。

我已阅读 OWASP 网站上的说明, ,但我不太明白

这是 CSRF 的一个例子吗?我该如何防止这种情况发生?我能想到的最好的办法就是在链接中添加一些东西,比如哈希值。但是在所有链接的末尾添加一些东西会非常令人恼火。难道就没有其他办法可以做到这一点吗?

另一件事可能有人可以给我一些其他的例子,因为这个网站对我来说似乎相当模糊。

有帮助吗?

解决方案

如果满足以下条件,这可能成为 CSRF 的示例:

  • 该链接已获取 (通过 <img> 标签,例如) :伪造
  • 来自另一个网站:跨站点


例如,如果我可以注入这个 <img> stackoverflow 的 HTML 源代码中的标签 (我可以,因为 stackoverflow 允许人们使用 <img> 他的帖子中的标签) :

<img src="http://mysite.com/vote/30" />

您只会投票支持该项目;-)


通常使用的解决方案是在 URL 中放置一个具有有限生命周期的令牌,并且在获取 URL 时检查该令牌是否仍然有效。

基本想法是:

  • 生成页面时:
    • 生成一个唯一的令牌
    • 将其存储在用户的会话中
    • 并将其放置在页面的链接中——如下所示: http://mysite.com/vote/30?token=AZERTYUHQNWGST
  • 当投票页面被调用时:
    • 检查 URL 中是否存在令牌
    • 检查它是否存在于用户会话中
    • 如果不是 => 不登记投票

想法是:

  • 代币的生命周期不长,而且很难猜测
  • 这意味着你的 攻击者 :
    • 只有几分钟的时间窗口,在此期间他的注射有效
    • 一定要善于猜测^^
    • 必须为每个用户生成不同的页面。


另请注意,用户离开您的网站后会话保持活动状态的时间越短,当他访问不良网站时会话仍然有效的风险就越小。

但在这里,你必须在安全性和用户友好性之间做出选择......


另一个想法 (这并不完全安全,但有助于防止那些不知道如何强制 POST 请求的人), ,将仅在人们投票时接受 POST 请求:

  • 浏览器正在发送注入标签的 GET 请求
  • 由于这个 URL 正在修改一些数据,无论如何,它不应该与 GET 一起使用,而只能与 POST 一起使用

但请注意,这并不完全安全:它是 (大概 ?) 可以使用一些 Javascript 来强制/伪造 POST 请求。

其他提示

首先,GET请求不应该被用于改变状态的服务器上,这样的投票服务,我会建议POST / PUT。这只是一个指南,但一个聪明的一个。

所以你的问题,CSRF是一个客户端问题,所以没关系样的服务器语言,你(你的情况PHP)使用什么。标准解决方法是相同的,并且是这样的:有在URI / POST数据的随机值,并在Cookie头部的值相同。如果这些比赛,你可以肯定没有CSRF。有一个关于如何在这里可以在计算器上就做出大量的信息。 这个。结果 祝你好运!

OWASP对PHP一个CSRFGuard,并为ESAPI PHP,我写了一个很久以前的XMB - > UltimaBB - > GaiaBB。

HTTP: //code.google.com/p/gaiabb-olpc/source/search?q=function+get_new_token&origq=function+get_new_token&btnG=Search+Trunk

看来一些其他人已经清理的代码并允许更强的令牌:

https://www.owasp.org/index.php/PHP_CSRF_Guard

感谢, 安德鲁

CSRF 攻击中有 3 名玩家

  1. 受害者网站(您的示例中的投票网站)[知道他登录的用户cookie]
  2. 你客户的 浏览器 (当他登录时)[知道他的饼干]
  3. 攻击者网站[不知道登录用户的cookie]

CSRF 攻击取决于 2 个事实

  1. 浏览器会根据每个请求自动发送 cookie
  2. 我们依靠 cookie 来识别我们的登录用户(例如: setcookie("sessionID", "0123456789ABCDEF", time()+3600); )

如果攻击者可以通过其他方式让登录用户请求此

// http://victim.website/vote/30

例如,通过将链接放在攻击者网站上或通过电子邮件发送,登录的客户端浏览器将随此请求一起发送识别cookie(sessionID),这将使受害者网站认为他的登录用户确实想要投票!

但是,如果受害者的网站更聪明,并使用附加的 GET 或 POST 参数(而不是 cookie)来验证其登录用户的请求,那么攻击者现在就会遇到问题,因为 GET 和 POST 参数不会由浏览器自动发送,并且他已经猜一下。

// http://victim.website/vote/30?csrfSecret=0123456789ABCDEF

攻击者不知道 csrfSecret 参数是受害者网站与其客户端之间的秘密(就像会话令牌一样),因此攻击者无法构建他想要伪造请求的 URL。

同样,如果投票是通过 POST 请求完成的,攻击者将无法在他的网站(或第三方网站)上制作表单,因为他不知道受害者网站与其用户之间的秘密。

<form method="post" action="http://victim.website/vote" >
    <input type="hidden" name="vote" value="30">
    <input type="hidden" name="csrfSecret" value="????? I don't know it :(">
</form>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top