What is GraphQL Security?
GraphQL gives clients the power to ask for exactly the data they need. That flexibility is also its biggest risk. If your API doesn't set boundaries, anyone can send a query that recurses ten levels deep, pulling related objects inside related objects until your server runs out of memory.
Introspection is GraphQL's built-in documentation system. In development, it's what powers autocomplete in your IDE. In production, it hands attackers a complete map of your data model — every type, every field, every connection — without them guessing a single endpoint.
Unlike REST APIs where each endpoint is a known surface, a GraphQL API is a single endpoint with an unlimited query space. Without rate limiting, depth limits, and complexity analysis, that single endpoint becomes an open door to denial-of-service and data discovery attacks.
How does GraphQL Security work?
The most common GraphQL security gap is an Apollo Server (or similar) running in production with introspection enabled and no query depth restrictions. Attackers first run an introspection query to map the schema, then craft deeply nested or aliased queries to exhaust resources or extract data.
Here's a typical vulnerable Apollo Server setup:
// server.ts
import { ApolloServer } from '@apollo/server';
const server = new ApolloServer({
typeDefs,
resolvers,
// introspection defaults to true — schema is public
// no depth limit — queries can nest indefinitely
});
// An attacker sends:
// { __schema { types { fields { type { fields { ... } } } } } }
// Then crafts: { user(id: 1) { posts { comments { author { posts { comments { ... } } } } } } }// server.ts
import { ApolloServer } from '@apollo/server';
import depthLimit from 'graphql-depth-limit';
import { createComplexityLimitRule } from 'graphql-validation-complexity';
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== 'production',
validationRules: [
depthLimit(5),
createComplexityLimitRule(1000),
],
});Why do AI tools generate GraphQL Security vulnerabilities?
AI code generators follow tutorials and documentation that prioritize getting a GraphQL server running. Security hardening is rarely part of the initial setup, and the defaults are permissive by design.
- Tutorials leave introspection on. Almost every GraphQL tutorial uses introspection for demo purposes. The AI learned from those examples and reproduces the same defaults.
- Depth limiting requires extra packages. Libraries like <code>graphql-depth-limit</code> aren't part of the core Apollo setup. The AI won't add dependencies you didn't ask for.
- Query complexity is domain-specific. The right depth limit depends on your schema shape. The AI can't know that your <code>User → Posts → Comments → Author</code> chain creates a dangerous recursion path.
The result is a GraphQL API that works perfectly in development and ships to production with its entire schema visible and no limits on query complexity. It takes one introspection query for an attacker to know exactly what to ask for.
Common GraphQL Security patterns
Introspection enabled in production
The default for most GraphQL frameworks. Exposes your entire type system to anyone who asks.
Deeply nested queries
Recursive relationships like User → Posts → Comments → Author → Posts with no depth cap.
Query aliasing for amplification
Sending the same expensive query 100 times in one request using GraphQL aliases.
Missing per-field authorization
Relying on top-level auth but exposing sensitive fields (email, role, internal IDs) on nested types.
How Flowpatrol detects GraphQL Security
Flowpatrol probes your GraphQL endpoint the same way an attacker would — starting with schema discovery and escalating to resource abuse:
- 1Sends an introspection query to check if the schema is publicly accessible.
- 2Maps the type graph and identifies recursive relationships that enable deep nesting.
- 3Tests depth and complexity limits by sending progressively deeper queries to find the breaking point.
- 4Reports exposed fields with the exact introspection response and nested query payloads that worked.
Most scanners treat GraphQL as a single endpoint and move on. Flowpatrol understands the query language and tests the boundaries that actually matter.
Related terms
Check your GraphQL API.
Flowpatrol tests introspection, query depth, and field-level access on your GraphQL endpoints. Paste your URL.
Try it free