一尘不染

PHP中的CSRF(跨站点请求伪造)攻击示例和预防

php

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

http://mysite.com/vote/25

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

http://mysite.com/vote/30

那么投票将成为他不希望这样做的地方。

我已经在OWASP网站上阅读了说明,但是我不太理解

这是CSRF的示例,如何防止这种情况发生?我能想到的最好的事情就是在链接中添加一些内容,例如哈希。但是,在所有链接的末尾放置一些内容将非常令人讨厌。有没有其他方法可以做到这一点。

有人可能会给我另一个例子,因为这个网站对我来说似乎很陌生。


阅读 328

收藏
2020-05-26

共1个答案

一尘不染

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

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

例如,如果我可以将此<img>标签注入stackoverflow的HTML源代码中
(并且我可以,因为允许一个人<img>在他的帖子中使用标签)

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

您只需为该项目投票;-)

通常使用的解决方案是将寿命有限的令牌放置在URL中,并在提取URL时检查此令牌是否仍然有效。

基本思想是:

  • 生成页面时:
    • 生成唯一令牌
    • 将其存储在用户的会话中
    • 并将其放在页面的链接中-看起来像这样: http://mysite.com/vote/30?token=AZERTYUHQNWGST
  • 调用投票页面时:
    • 检查令牌是否存在于URL中
    • 检查它是否存在于用户会话中
    • 如果不是=>不要注册投票

这里的想法是:

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

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

但是在这里,您必须在安全性和用户友好性之间进行选择。

另一个想法 (虽然不是很安全,但是对伙计们的帮助不会知道如何强制执行POST请求) 是仅在人们投票时才接受POST请求:

  • 浏览器正在发送GET请求以插入标记
  • 无论如何,由于此网址正在修改某些数据,因此它不应与GET一起使用,而只能与POST一起使用

但是请注意,这并不是绝对安全的 :(可能是?) 可以使用一些Javascript强制/伪造POST请求。

2020-05-26