2010-03-26 60 views
44

例如攻击和防范我有一个网站,人们可以把这样的投票:CSRF(跨站请求伪造)在PHP

http://mysite.com/vote/25 

这将会把我只想就项目25票使其可用于注册用户,并且只有当他们想要这样做时。现在我知道,当有人忙在网站上,有人给了他们这样一个链接:

http://mysite.com/vote/30 

然后投票将在项目为他的地方没有他想做到这一点。

我看了explanation on the OWASP website,但我真的不明白

这是CSRF的一个例子,我怎样才能避免这种情况。我能想到的最好的事情就是像链接一样添加链接。但是,将所有链接的末尾放在一起会让人非常恼火。有没有其他的方式来做到这一点。

另一件事可能有人可能会给我一些其他的例子,因为该网站似乎相当神职我。

回答

82

这可能成为CSRF的一个例子,如果:

  • 链接被取出(经由<img>标签,例如):伪造
  • 从另一个网站:跨站点


例如,如果我可以将此<img>标记注入到stackoverflow的HTML源代码(我可以,作为stackover流允许使用他的职位<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请求。

+2

你是正确的,这是我们所容易伪造作为POST请求的GET。虽然我不同意必须有一个过期令牌。如果攻击者能够掌握会话数据,那么比其他额外投票更麻烦。但是,您的建议修复仍然有效,因为关键只是在Cookie和请求数据中具有令牌/随机值(保存在Cookie中或与用户会话密钥绑定)。 – MyGGaN 2010-03-26 22:57:56

+0

谢谢你的建议。我将更改所有链接以获取此令牌。我必须同意这是一个非常节省的方法。但是我不会执行令牌过期,我同意MygGaN。 – 2010-03-27 06:10:21

+0

你们中的任何一个人都有一个想法,当我使用AJAX进行投票时该怎么做。我应该在用户在页面上时重复使用相同的密钥,并且只在刷新时生成新的令牌。或者,我必须在投票完成后为所有链接提供新的令牌。 – 2010-03-27 06:13:31

17

首先,GET请求不应该用来改变服务器上的状态,所以对于你的投票服务,我会推荐POST/PUT。这只是一个指导方针,但是一个切肉刀。

因此,对于您的问题,CSRF是一个客户端问题,因此使用什么样的服务器语言(您的情况下使用PHP)并不重要。标准修订是相同的,如下所示:在URI/POST数据中具有一个随机值,并在Cookie标头中具有相同的值。如果这些匹配,你可以肯定没有CSRF。有很多关于如何在StackOverflow中完成的信息,例如。 this one
祝你好运!

相关问题