跳转至

GraphQL Circular References

GraphQL 循环引用

描述

GraphQL 允许客户端请求特定数据,可以利用其灵活性来创建复杂或递归查询。当对象类型直接或间接通过其他类型引用回自身时,就会发生循环引用。

例如:

 query CircularReferences  {
     user {
       friends {
         user {
           friends {
             user {
               __typename
             }
           }
         }
       }
     }
   }

GraphQL 中循环引用的安全影响:

  • 拒绝服务:通过发送包含太多嵌套引用的大型查询,攻击者可能会使服务器不堪重负,导致其运行缓慢或崩溃。
  • 资源耗尽:服务器在处理查询时可能会耗尽内存或 CPU 资源,从而导致性能下降或服务不可用。

建议

为了降低 GraphQL 中发生循环引用的风险,您可以遵循以下建议: 1. 深度限制: 实现一个中间件来检查查询的深度,并在超过限制时抛出错误。 示例:

class DepthAnalysisMiddleware:
    def resolve(self, next, root, info, **args):
        if info.operation.selection_set:
            depth = 0
            for field in info.operation.selection_set.selections:
                depth = max(depth, self._get_depth(field))
            if depth > 3:
                raise Exception('Query depth is too high')
        return next(root, info, **args)

    def _get_depth(self, field):
        if field.selection_set:
            return 1 + max(self._get_depth(f) for f in field.selection_set.selections)
        return 1
  1. 循环引用检测: 重新设计模式以避免循环引用。 循环引用示例:
class User(graphene.ObjectType):
    id = graphene.ID()
    name = graphene.String()
    friends = graphene.List(lambda: User)

    def resolve_friends(self, info):
        return [User(id=1, name='Alice'), User(id=2, name='Bob')]

重新设计的模式示例:

  class FriendProfile(graphene.ObjectType):
      id = graphene.ID()
      name = graphene.String()

  class User(graphene.ObjectType):
      id = graphene.ID()
      name = graphene.String()
      friends = graphene.List(FriendProfile)

      def resolve_friends(self, info):
          return [FriendProfile(id=1, name='Alice'), FriendProfile(id=2, name='Bob')]
      const FriendProfile = new GraphQLObjectType({
          name: 'FriendProfile',
          fields: {
              id: { type: GraphQLID },
              name: { type: GraphQLString }
          }
      });

      const User = new GraphQLObjectType({
          name: 'User',
          fields: {
              id: { type: GraphQLID },
              name: { type: GraphQLString },
              friends: { type: new GraphQLList(FriendProfile) }
          }
      });  

链接

标准

  • CWE_TOP_25:
    • CWE_400
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
    • REQ_11_3
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_ASVS_L3:
    • V13_4_1
  • 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