TL;DR
GraphQL has unique security concerns. Disable introspection in production. Limit query depth and complexity, and lock down authorization at the field level, not just the query level. Unlike REST, GraphQL exposes your entire schema by default and lets clients ask for exactly what they want, which opens attack surfaces REST never had to worry about.
Common GraphQL Security Issues
1. Introspection Enabled in Production
Introspection lets anyone query your entire schema. Every type, every field, every relationship between them, all visible to whoever asks. We flag exposed GraphQL Playground and GraphiQL endpoints in scans regularly; it's one of the more common ways a schema ends up public by accident.
// Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== 'production'
});
2. Deep/Nested Queries (DoS)
# Attacker creates deeply nested query
query {
user(id: 1) {
friends {
friends {
friends {
friends {
friends { # ... continues 100 levels deep
}
}
}
}
}
}
}
3. Batching Attacks
# Send 1000 login attempts in one request
query {
a: login(email: "user@x.com", pass: "pass1") { token }
b: login(email: "user@x.com", pass: "pass2") { token }
c: login(email: "user@x.com", pass: "pass3") { token }
# ... 997 more attempts
}
How to Secure GraphQL
- Disable introspection in production environments
- Limit query depth using graphql-depth-limit
- Limit query complexity based on field costs
- Rate limit by query complexity, not just requests
- Authorize at field level, not just query level
- Limit batching or apply rate limits per operation
Is GraphQL less secure than REST?
Not inherently, but it has different security concerns. REST naturally limits what clients can request, while GraphQL requires explicit limits. Both can be secured properly.
Should I use persisted queries?
Yes, for production. Persisted queries only allow pre-approved queries, preventing arbitrary query attacks. This eliminates most GraphQL-specific vulnerabilities.
Audit Your GraphQL API
Our scanner tests GraphQL endpoints for common vulnerabilities.