GraphQL Abuse V34 · v1.6
Single GraphQL query asks for the same field a thousand times via aliases (a:user{} b:user{} c:user{}...) for a 1000x backend cost amplification. Or a self-referential fragment spins the executor. graphqlGuard rejects all four classes.
What it catches
- Depth bomb: selection-set nesting beyond
max_depth(default 7) - Introspection in production:
__schema,__type,__typenamequeries whenblock_introspection: true - Alias bomb (v1.6): alias count beyond
max_aliases(default 50) - Fragment cycle (v1.6):
fragment A on User { ...A }self-reference or longer cycles A → B → A - Length limit: query string longer than
max_length
Precedence (first violation wins): depth → introspection → aliases → fragment_cycle → length.
Sample
// Alias bomb
query AmplificationAttack {
a: user(id: "1") { name email }
b: user(id: "1") { name email }
c: user(id: "1") { name email }
// ... repeated 1000x ...
}
// graphqlGuard returns:
{ ok: false, violation: "aliases", aliases: 1000 }
// Fragment cycle
query { ...A }
fragment A on User { id ...B }
fragment B on User { id ...A }
// graphqlGuard returns:
{ ok: false, violation: "fragment_cycle" }
Configuration
import { graphqlGuard } from '@arcis/node';
app.use('/graphql', graphqlGuard({
maxDepth: 7,
maxAliases: 50,
blockIntrospection: process.env.NODE_ENV === 'production',
blockFragmentCycles: true,
maxLength: 10000
}));
Disable per route
Apply only to your /graphql route. The guard is opt-in and route-scoped, so other endpoints are not affected.
References
- CWE-770: Allocation of Resources Without Limits
- Escape: GraphQL security best practices
- v1.6 changelog: V34 alias bomb + fragment cycle
Pair with persisted queries. For production-grade abuse prevention, allow only persisted (hashed) queries from your clients. graphqlGuard is what catches abuse on the routes where you still accept ad-hoc queries (admin tooling, GraphiQL).