在基于AJAX的应用程序中使用令牌防止CSRF

时间:2014-05-03 17:59:01

标签: php security csrf phalcon

我在我的应用程序中使用令牌来防止CSRF攻击。但是这个应用程序是单页面和基于AJAX的,所以我需要找到一种方法在一个页面中为N个动作提供有效的令牌:

e.g。文档片段加载了3个可能的操作,每个操作都需要一个令牌才能正常工作,但服务器端只有一个有效的令牌...

由于每个令牌只是一个encrypted nonce(值不是基于特定形式),我想到了为每个动作自动化令牌分配的想法,如下所示:

  1. 该应用程序拦截AJAX呼叫,并检查它是否是敏感操作(即删除用户)
  2. 在操作进行之前向服务器请求令牌
  3. 生成令牌,然后将其添加到操作请求
  4. 自请求以来执行的操作包含有效令牌
  5. 对通过AJAX执行的任何后续操作执行相同的操作
  6. 我认为该方法不够有效,因为攻击者可以使用与我的App完全相同的脚本(检索令牌并附加到请求中)。

    如何改进我的方法以有效对抗CSRF攻击?

    其他信息:我的后端环境是PHP / Phalcon,令牌是generated using Phalcon

2 个答案:

答案 0 :(得分:3)

比仅使用AJAX标记更简单的方法可能是检查只能出现在您自己域名的AJAX请求中的标题。

有两个选项:

Origin标头也可以用于普通的HTML表单提交,您可以在表单提交处理之前验证它是否包含您自己网站的URL。

如果您决定检查X-Requested-With标头,则需要确保将其添加到每个AJAX请求客户端(JQuery默认会这样做)。由于此标头无法跨域发送(未经您的服务器首先同意浏览器),检查是否存在并设置为您自己的值(例如“XMLHttpRequest”)将验证该请求不是CSRF攻击

答案 1 :(得分:2)

前一段时间我不得不处理类似的事情。使用ajax请求nonce是一个非常糟糕的主意 - 恕我直言,如果攻击者可以在不重新加载页面的情况下简单地生成它,则无效。我最终实现了以下内容:

  1. Nonce模块(操作的大脑),用于处理nonce的创建,销毁,验证和层次结构(例如,具有多个输入的一页的子nonce)。
  2. 每当呈现表单/特定输入时,将生成随机数并存储在具有过期时间戳的会话中。
  3. 当用户完成动作/表单/页面时,将破坏具有其层次结构的随机数。如果操作重复,请求可能会返回新的nonce。
  4. 生成新的nonce时会检查旧的nonce,并删除过期的nonce。
  5. 它的主要问题在于决定nonce何时到期并清理它们,因为它们像类固醇上的细菌一样生长。您不希望用户提交一个已打开一小时的表单并因为nonce过期/删除而卡住。在这些情况下,您可以使用重新生成的随机数返回“超时,请再试一次”消息,因此根据以下请求,一切都会通过。

    正如已经建议的那样,没有任何东西是100%防弹,在大多数情况下是过度杀伤。我认为这种方法在偏执和不浪费时间之间是一个很好的平衡。它对我有多大帮助吗?与极大地改善安全性相比,它做了更多的偏执。

    从逻辑上思考,在这些情况下你能做的最好的事情就是分析请求背后的行为,如果他们有疑问就把它们计时。例如,来自一个ip,跟踪鼠标/键盘的每分钟20个请求,确保它们在请求之间处于活动状态。换句话说,确保请求不是自动化的,而不是确保它们带有有效的随机数。