首页 文章

你如何防止对GraphQL / Apollo服务器的嵌套攻击?

提问于
浏览
41

如何使用以下查询阻止对Apollo服务器的嵌套攻击:

{
  authors {
    firstName
    posts {
      title
      author {
        firstName
        posts{
          title
          author {
            firstName
            posts {
              title
              [n author]
                [n post]
            }
          }
        }
      }
    }
  }
}

换句话说,如何限制查询中提交的递归数量?这可能是潜在的服务器漏洞 .

4 回答

  • 2

    截至撰写本文时,GraphQL-JS或Apollo Server中没有内置功能来处理这一问题,但随着GraphQL变得越来越流行,它肯定会有一个简单的解决方案 . 这个问题可以通过堆栈的多个层次上的几种方法来解决,并且还应该始终与速率限制相结合,以便人们不能向您的服务器发送太多查询(这也是REST的潜在问题) .

    我将列出我能想到的所有不同方法,并且我将尽力使这个答案保持最新,因为这些解决方案是在各种GraphQL服务器中实现的 . 其中一些非常简单,有些则更复杂 .

    • Query validation :在每个GraphQL服务器中,运行查询的第一步是验证 - 这是服务器尝试确定查询中是否存在任何严重错误的地方,这样我们就可以避免使用实际的服务器资源预先存在一些语法错误或无效参数 . GraphQL-JS附带a selection of default rules,其格式与ESLint非常相似 . 就像有一个检测infinite cycles in fragments的规则一样,可以编写一个验证规则来检测具有太多嵌套的查询并在验证阶段拒绝它们 .

    • Query timeout :如果它是一个不太难以推理的硬限制,并且(2)这也将有助于其中一个后端采取不合理的长时间响应的情况 . 在许多情况下,您的应用的用户更愿意在等待10秒钟时丢失字段以获得响应 .

    • Query whitelisting :这可能是涉及最多的方法,但您可以提前编译允许的查询列表,并检查针对该列表的任何传入查询 . 如果您的查询是完全静态的(您不在客户端上使用Relay之类的任何动态查询生成),这是最可靠的方法 . 您可以使用自动化工具在部署时从应用程序中提取查询字符串,以便在开发中编写您想要的任何查询,但在 生产环境 中只会将您想要的查询通过 . 此方法的另一个好处是您可以完全跳过查询验证,因为您知道所有可能的查询都已有效 . 有关静态查询和白名单的更多好处,请阅读以下文章:https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a

    • Query cost limiting :(在编辑中添加)与查询超时类似,您可以在查询执行期间为不同的操作分配成本,例如数据库查询,并限制客户端每个查询可以使用的总成本 . 这可以与限制单个查询的最大并行度相结合,这样您就可以阻止客户端向您的后端发送启动数千个并行请求的内容 .

    (1)和(2)特别是默认情况下每个GraphQL服务器都应具有的功能,特别是因为许多新开发人员可能不会意识到这些问题 . (3)仅适用于某些类型的应用程序,但在有非常严格的性能或安全要求时可能是一个不错的选择 .

  • 41

    为了补充stubailo的答案中的第(4)点,这里有一些Node.js实现,它们对传入的GraphQL文档施加了成本和深度限制 .

    这些是补充验证阶段的自定义规则 .

  • 8

    查询白名单的变体是 query signing .

    在构建过程中,使用与服务器共享但未与客户端捆绑的密钥对每个查询进行加密签名 . 然后在运行时,服务器可以验证查询是否为正版 .

    与白名单相比的优势在于,在客户端中编写查询不需要对服务器进行任何更改 . 如果多个客户端访问同一服务器(例如,Web,桌面和移动应用程序),这尤其有用 .

  • 1

    对于查询成本限制,您可以使用graphql-cost-analysis

    这是一个验证规则,在执行查询之前解析查询 . 在GraphQL服务器中,您只需为所需的模式类型映射的每个字段分配成本配置 .

相关问题