跳转至

Array-Based Batch Queries

基于数组的批量查询

描述

GraphQL 中的基于数组的批量查询发生在攻击者使用数组结构在单个请求中发送多个查询时,这可能会使服务器的处理能力超载。

在 GraphQL 中,客户端通常允许每个请求发送单个查询。但是,如果没有得到适当的限制,攻击者可以使用数组将多个查询捆绑到单个请求中。这可能会因消耗过多的服务器资源、降低性能或导致服务中断而导致拒绝服务 (DoS) 攻击。

示例:

[
  { query: "{ user(id: 1) { name } }" },
  { query: "{ user(id: 2) { name } }" },
  { query: "{ user(id: 3) { name } }" }
]

基于数组的批量查询的安全影响:

拒绝服务: 攻击者可以在单个请求中发送大量查询批次,迫使服务器同时处理众多操作。这可能会导致资源耗尽和潜在的服务崩溃。 资源耗尽: 与字段重复类似,基于数组的批量查询可以通过在一次调用中使用大量查询使服务器超载来增加 CPU 和内存使用率。 服务中断: 如果不加控制,基于数组的批量查询可以使合法用户无法使用 GraphQL API,从而导致系统停机或性能下降。

建议

为了减轻 GraphQL 中基于数组的批量查询攻击(将多个查询捆绑到一个请求中)的风险,您可以应用以下策略:

  • 实施查询复杂性限制:设置规则,以考虑在单个请求中处理的查询数量。这有助于限制服务器上的负载,并防止攻击者发送过大的查询批次。
  • 限制每个请求的查询数量:在服务器端实施有关单个批次中可发送的查询数量的限制。像 GraphQL Armor 这样的工具可以帮助施加限制,并防止通过基于数组的批量查询导致资源过载。
  // Configuring for GraphQL Armor
  GraphQLArmorConfig({
      maxBatchQueries: {
          // Enable or disable the plugin | default: true
          enabled: true,

          // Set the maximum number of queries allowed per request | default: 5
          n: 5,

          // Callbacks to execute when a query batch is accepted
          onAccept: [],

          // Callbacks to execute when a query batch is rejected
          onReject: [],

          // Propagate rejection details to the client | default: true
          propagateOnRejection: true,
      }
  });
  import graphql
  from graphql.language import ast
  from graphql.language import parser
  from settings import api

  def validate_batch_queries(query: str) -> None:
      """
      This validation prevents the execution of requests containing excessive
      batch queries to avoid overloading the server.
      """
      class BatchQueryParser(parser.Parser):
          def parse_batch_queries(self) -> list[ast.OperationDefinitionNode]:
              query_count = 0
              while self.peek(graphql.TokenKind.BRACKET_L):
                  self.parse_operation_definition()
                  query_count += 1
                  if query_count > api.API_MAX_BATCH_QUERIES:
                      raise graphql.GraphQLError("Exception - Max batch queries exceeded")
              return []

      ast_parser = BatchQueryParser(query)
      ast_parser.parse_document()

链接

标准

  • CWE_TOP_25:
    • CWE_20
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
    • REQ_11_3
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_ASVS_L2:
    • V5_3_3
    • V5_3_4
    • V9_1_1
    • V12_1_1
    • V12_1_2
  • OWASP_ASVS_L3:
    • V5_3_3
    • V5_3_4
    • V12_1_1
    • V12_1_2
    • V12_1_3
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
    • CC_9_1
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213