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

Php 在基于AJAX的应用程序中使用令牌防止CSRF,php,security,csrf,phalcon,Php,Security,Csrf,Phalcon,我在应用程序中使用令牌来防止CSRF攻击。但是这个应用程序是单页的,并且非常基于AJAX,所以我需要找到一种方法,为单页中的N个操作提供有效的令牌: e、 一个文档片段加载3个可能的操作,每个操作需要一个令牌才能正常工作,但服务器端每次只有一个有效令牌 由于每个令牌都只是一个(值不是基于特定的形式),因此我想到了为每个操作自动分配令牌的想法,如下所示: 应用程序拦截AJAX调用,并检查它是否是敏感操作(即删除用户) 在操作继续之前,将向服务器请求令牌 生成令牌,然后将其添加到操作请求中 自请求包

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

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

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

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

    如何改进我的方法以有效抵御CSRF攻击?


    附加信息:我的后端环境是PHP/而令牌是。

    我不久前不得不处理类似的问题。使用ajax请求nonce是一个非常糟糕的主意——IMHO,如果攻击者可以简单地生成nonce而不重新加载页面,那么使用nonce的整个意义就失效了。我最终实现了以下目标:

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

    如前所述,没有什么是100%防弹的,在大多数情况下是杀伤力过大。我认为这种方法在偏执和不浪费时间之间取得了很好的平衡。这对我有很大帮助吗?与显著提高安全性相比,它更偏执


    从逻辑上看,在这些情况下,你能做的最好的事情就是分析请求背后的行为,如果他们怀疑,就暂停请求。例如,每分钟从一个ip发出20个请求,跟踪鼠标/键盘,确保它们在请求之间处于活动状态。换句话说,确保请求不是自动的,而不是确保它们带有有效的nonce。

    一个比仅对AJAX使用令牌更简单的方法可能是检查只能出现在来自您自己域的AJAX请求中的头

    有两种选择:

    Origin
    标题也可用于正常的HTML表单提交,在表单提交进行处理之前,您需要验证它是否包含您自己站点的URL


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

    攻击者如何登录并执行该请求,假设您使用会话登录,并且不允许未登录的用户删除用户?如果删除用户是针对您的真正CSRF攻击,那么攻击者如何知道您的nonce?如果它是一个公共API是的,他们可以先抓取你的页面,获得当前状态,然后执行请求,你不能100%停止,你可以添加一些层,但仍然可以。您甚至可以使用加密字符串(带有与用户相关的参数)来代替nonce,但通常是它的过度使用。“每个操作都需要一个令牌才能正常工作,但服务器端每次只有一个有效令牌…”–那么改变一下:为每个可能的操作生成不同的令牌。您在解决方案中考虑过XSS攻击吗?任务是防止不需要的数据自由提交到服务器。这是一个非常通用的解决方案,它不是100%防弹的,但它确实阻止了大多数自动表单提交。XSS是一个完全不同的故事,我根本不知道使用令牌如何帮助解决它:)它只能通过使用常识、不工作到深夜以及测试代码是否存在漏洞来防止。@IanBytchek整个维基都充满了必须知道的信息,只剩下决定什么才是真正必须知道的:P@SilverlightFox,浏览,早期的浏览器不支持CORS。所以,这些技术大多只应用于AJAX请求,对吗?我假设,如果我编译了一个有效的请求,那么可以使用curl绕过这个问题。阅读良好–@IanBytchek是的,
    Origin
    头只会出现在CORS支持的浏览器中,但对
    X-request-With
    的限制也应适用于CORS之前的跨域请求。警告:结果可能因浏览器而异。是的,它们可以被
    curl
    欺骗,但在这种情况下,攻击者不会让浏览器注入受害者的cookie(我怀疑您现在已经知道了这一点)。