跳转至

Field Duplication in GraphQL API

GraphQL API中的字段重复

描述

当攻击者发送重复请求同一字段的查询,导致服务器的处理能力超载时,就会发生GraphQL中的字段重复(Field Duplication)。

在GraphQL中,客户端可以在一次查询中请求多个字段,包括多次请求同一个字段。但是,字段的过度重复可能会消耗服务器资源,从而导致拒绝服务(DoS)攻击。这会降低性能或导致服务中断。 示例:

query overload {
  user {
    id
    id
    id
    id
    id
    ...
  }
}

字段重复的安全影响:

  • 拒绝服务(Denial of Service): 通过在查询中重复相同的字段,攻击者可以迫使服务器反复处理相同的请求,导致资源过度使用和潜在的服务崩溃。
  • 资源耗尽(Resource Exhaustion): 与别名重载类似,此攻击可能导致CPU和内存使用量激增,从而降低系统速度并影响整体性能。
  • 服务中断: 如果不加以缓解,字段重复攻击可能会使合法的用户无法使用GraphQL API,从而导致系统停机或服务降级。

建议

为了降低字段重复攻击的风险,您可以采取以下措施:

  • 实施查询复杂性限制: 强制执行查询复杂性规则,将重复的字段视为查询总成本的一部分。这有助于限制处理的重复字段的数量,从而保护服务器免受资源耗尽的影响。
  • 限制字段重复次数: 在服务器端配置对单个GraphQL查询中一个字段可以被重复的次数的限制。您可以使用GraphQL Armor等工具来实施此类限制,并防止字段重复导致超载。
 // Configuring for GraphQL Armor
 GraphQLArmorConfig({
         maxFieldDuplicates: {
    // Enable or disable the plugin | default: true
             enabled: true,

    // Set the maximum number of field duplications allowed per query | default: 10
             n: 10,

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

    // Callbacks to execute when a query 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_field_duplicates(query: str) -> None:
     """
         This validation prevents the execution of queries containing excessive
         duplicated fields to avoid overloading the server.
         """
         class FieldDuplicationParser(parser.Parser):
             def parse_duplicates(self) -> list[ast.FieldNode]:
                     field_counts = {}
                         while self.peek(graphql.TokenKind.NAME):
                             field_name = self.parse_field().name.value
                                 field_counts[field_name] = field_counts.get(field_name, 0) + 1
                                 if field_counts[field_name] > api.API_MAX_FIELD_DUPLICATES:
                                     raise graphql.GraphQLError("Exception - Max field duplicates exceeded")
                                 return []
                 ast_parser = FieldDuplicationParser(query)
         ast_parser.parse_document()

链接

标准

  • CWE_TOP_25:
    • CWE_400
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
    • REQ_11_3
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_ASVS_L2:
    • V4_1_3
    • V4_1_5
    • V5_3_3
    • V5_3_4
    • V9_1_1
    • V9_1_2
    • V12_1_1
    • V12_1_2
  • OWASP_ASVS_L3:
    • V4_1_3
    • V4_1_5
    • V5_3_3
    • V5_3_4
    • V9_1_1
    • V9_1_2
    • 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