Circular Fragment in GraphQL
GraphQL 中的循环片段
描述
GraphQL 中的循环片段(Circular fragments)是指 GraphQL 查询中的片段相互引用,从而导致循环引用的情况。这可能会引发无限循环、资源耗尽和拒绝服务(DoS)攻击等问题。攻击者可以利用这一点使 GraphQL 服务器不堪重负,使其对合法用户不可用或响应缓慢。
GraphQL 中循环片段的安全影响:
1. 拒绝服务(DoS): 循环片段引用可能导致服务器无休止地解析查询,消耗过多资源并最终导致崩溃或速度变慢。 2. 资源耗尽: 无限的片段循环可能导致高 CPU 和内存使用率,引起资源耗尽,从而降低应用程序或服务器的性能。 3. 查询复杂性漏洞利用: 攻击者可以利用循环片段构造复杂的查询,以利用 GraphQL 服务器中缺乏深度或递归限制的弱点。
循环片段的一个基本示例如下所示:
fragment UserFields on User {
name
...MoreUserFields
}
fragment MoreUserFields on User {
email
...UserFields
}
在此示例中,UserFields 引用了 MoreUserFields,并且 MoreUserFields 引用了 UserFields,从而创建了一个循环引用。
建议
为了缓解 GraphQL 中循环片段的风险,请考虑以下步骤:
1. 通过模式分析检测循环片段
对您的 GraphQL 模式(schema)和查询实施静态分析,以在循环引用被利用之前对其进行检测和阻止。一些 GraphQL 服务器库提供了用于分析模式的工具。
- Tooling: 使用 GraphQL linting 工具(如 GraphQL Code Generator 或 GraphQL Inspector)来检测循环片段并防止它们进入生产环境。
使用 GraphQL Code Generator 的示例:
npm install @graphql-codegen/cli
npx graphql-codegen init
您可以配置代码生成器输出模式验证,以检测 GraphQL 查询中潜在的循环片段问题。
2. 实施查询成本分析
使用查询复杂性分析为每个字段、片段或查询分配“成本”。当查询或片段超过预定义的成本阈值时,可以自动拒绝它。
- Tooling: 您可以使用 graphql-query-complexity 等库来计算查询成本并限制循环片段的影响。
使用 graphql-query-complexity 的 JavaScript 示例:
const { getComplexity, simpleEstimator } = require('graphql-query-complexity');
const server = new ApolloServer({
schema,
validationRules: [
queryComplexity({
estimators: [
simpleEstimator({ defaultComplexity: 1 })
],
maximumComplexity: 1000, // Queries that exceed this complexity will be rejected
onComplete: (complexity) => {
console.log('Query Complexity:', complexity);
},
}),
],
});
3. 强制执行深度和递归限制
一些 GraphQL 服务器实现允许您定义查询深度和递归的限制以防止资源耗尽。这有助于避免由循环片段引起的无限循环。
- Tooling: 例如,Apollo Server 支持查询深度限制,这可以防止过度的递归。
在 Apollo Server 中使用查询深度限制的示例:
const { ApolloServer } = require('apollo-server');
const depthLimit = require('graphql-depth-limit');
const server = new ApolloServer({
schema,
validationRules: [depthLimit(5)], // Set query depth limit to 5
});
4. 明智地使用片段
避免在复杂查询中过度使用片段。过度使用可能会导致性能下降,并增加了循环引用的可能性。相反,应考虑将复杂的查询拆分为多个较小的查询。
- Recommendation: 审查查询设计,并将片段的使用限制在特定的模块化数据块上。
示例:
query {
user(id: "1") {
name
email
posts {
title
content
}
}
}
与其将多个片段相互嵌套,不如使用像这样的简单查询。
链接
- Circular Fragment Exploitation in GraphQL with BurpSuite
- Managing Circular Imports in GraphQL Modules
标准
- 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