如何防止PHP,csrf,xsrf中的表单重放/中间人攻击

时间:2009-10-09 17:27:40

标签: php security forms csrf

我有一个网络表单,我正在使用PHP。我知道表格可以被操纵(我相信它被称为重播攻击或中间人攻击)。所以我想使用一些真实性令牌作为隐藏字段。

我所知道的威胁可能性是:

  • 攻击者劫持了合法用户的表格(我相信这是中间人攻击)
  • 合法用户本身就是攻击者:他获取表单,读取令牌但使用它发送危险数据(我相信这是重播攻击)

在我提出问题之前,如果我到目前为止所说的任何内容都不正确,请纠正我,因为我的理解可能存在缺陷。

现在回答问题:

  • 生成此令牌的最佳做法是什么,以便没有它的表单被拒绝(例如,salting?)。
  • 人们做了什么来确保令牌没有被重播。

基于评论的新小问题:

  • 会话劫持与中间人攻击相同吗?

4 个答案:

答案 0 :(得分:5)

你在标题中提到了CSRF,但在你的问题中没有真正涵盖它。

您可以详细了解online,但CSRF基本上是一种攻击,允许合法用户在不知情的情况下提交到网站。例如,如果SO没有防范此类攻击,我可以制作一个表单,当您点击我的这个糟糕形式时,会导致您的SO个人资料信息发生变化,期待其他事情发生(“赢得一百万美元!点击这里!!”)。此表单将使用您的浏览器Cookie以使用SO授权您,并使其显示为您合法地向您的个人资料提交更新。

为防止这种情况发生,你真的想做几件事:

  • 确保GET不会导致更新(例如,不要使用GET上的查询参数向用户的配置文件发布新状态更新)
  • 确保所有POST都附带一个隐藏字段,该字段允许您验证表单是由您的服务生成的,而不是由其他人生成的,并且它是针对目标用户的。因此,每次向服务器发送表单的html时,必须由服务器生成此隐藏字段,并且对于该会话的该用户应该是唯一的。

第二项的替代方法是检查引荐来源始终是您的站点或您期望POST的站点。我不鼓励这种情况用于非HTTPS站点,因为某些浏览器/网络硬件会删除引用者,并且引用者存在并不总是可靠。

答案 1 :(得分:3)

用于生成令牌的方法并不重要。 重要的是令牌只能使用一次。保留在用户会话中为用户生成的令牌列表。如果用户提交表单并且提交的令牌不在会话中,则可以拒绝该表单。

保护中间人有点困难。我见过的一种常见技术是在哈希函数中包含所有隐藏的表单字段以生成令牌,然后根据已知的隐藏字段重新生成令牌。然而,这只能防止隐藏的野外操纵,这可能不是中间人的最终目标。

当用户成功提交带有令牌的表单时,请从会话中删除令牌,因此该提交的任何重播 将失败。但是,所需要的只是用户再次请求表单生成另一个令牌。然后,该新令牌可用于后续的自动攻击。 换句话说,表单令牌对CSRF很有用,但对自动重播和中间人攻击不是很有效。

同样,您需要调整应用程序,不要求在表单上使用用户的后退按钮。如果他们的提交存在问题,您将需要将表单返回给用户,并填写他们的数据。如果用户按下她的后退按钮以更正错误,则她的提交将因为现在无效而失败令牌。

另外,坦率地说,当您需要担心请求重放和中间人攻击时,您的用户连接已经受到损害,并且您可能无法减轻任何损害。单独的SSL是针对MITM和重放的足够保护级别,如果你担心它,你将在SSL下运行......

答案 2 :(得分:1)

要生成该令牌,这是我使用的策略似乎运作良好。

  • 将Cookie设置为随机值(使用常规技巧在服务器上生成)并根据您的需要将其设置为过期。
  • 在提供带有表单的页面时,嵌入一个隐藏字段,其值等于此cookie的值。
  • 处理帖子时,请验证此字段是否存在,以及该值是否与用户的Cookie匹配

答案 3 :(得分:0)

csrf-magic是CSRF令牌的绝佳类,它会自动将它们放入您的页面

http://csrf.htmlpurifier.org/

" csrf-magic使用PHP的输出缓冲功能动态重写文档中的表单和脚本。它还将拦截POST请求并检查其令牌(使用各种算法;一些生成nonce,一些生成用户特定的令牌)。这意味着,对于带有表单的传统网站,您可以将csrf-magic放入应用程序并忘记它!"