GraphQL: flexibility for developers, attack surface for attackers
GraphQL has replaced REST in many modern applications. Its flexibility is its greatest strength — and its greatest weakness. Traditional vulnerability scanners, designed for REST, miss 6 categories of GraphQL-specific flaws.
Vulnerability 1: Introspection enabled in production
Introspection allows anyone to discover your entire schema — types, fields, mutations, queries. It's like giving an attacker the complete blueprint of your application. Scanners rarely check if introspection is disabled.
In audits, we send a simple __schema query and get the complete API map. In 80% of GraphQL applications we audit, introspection is active in production.
Vulnerability 2: Depth attacks
GraphQL allows nested queries: user { posts { comments { author { posts { comments... } } } } }. Without a depth limit, an attacker can build a query that consumes all server resources. This is a denial-of-service vector that scanners don't explore.
Vulnerability 3: Batching attacks
GraphQL accepts multiple queries in a single HTTP call. An attacker can send 1,000 login mutations in one request, bypassing rate limiting that operates per HTTP request. Scanners test endpoints one by one and don't detect this flaw.
Vulnerability 4: IDOR via Relay Global IDs
The Relay pattern uses base64-encoded global IDs (e.g., VXNlcjoxMjM= for User:123). An attacker can decode these IDs, increment the number, and access other users' objects. Scanners don't understand Relay ID semantics.
Vulnerability 5: Authorization bypass on nested resolvers
Authorization is often checked on the root resolver but not on nested resolvers. Example: the query user(id: me) verifies you're accessing your own profile. But user(id: me) { company { employees { salary } } } may expose all employees' salaries if the employees resolver doesn't re-check permissions.
This is the most dangerous and hardest-to-detect GraphQL flaw.
Vulnerability 6: Sensitive mutations without role verification
Mutations like deleteUser, updateRole, or exportData exist in the schema but don't verify the caller's role. Introspection reveals these mutations, and a simple call executes them.
Our GraphQL audit approach
We manually analyze the exposed schema, test depth and batching limits, verify authorization on every nested resolver, and identify unprotected sensitive mutations. This is expert work that scanners cannot do.
Related articles
Three adjacent analyses to keep exploring the same attack surface.
GraphQL: 5 specific attacks scanners miss
GraphQL-specific vulnerabilities that automated tools fail to detect: introspection, batching, deep queries, aliases, and injections.
WordPress REST API: 7 dangerous endpoints enabled by default
Your WordPress exposes sensitive data via REST API without you knowing. Here are 7 endpoints to check now.
Next.js: common security mistakes in Server Components applications
Exposed Server Actions, insecure data fetching, API route auth gaps, middleware bypass — the Next.js App Router flaws we find in audits.
Sources
Editorial analysis based on official vendor, project, and regulator documentation.
Related services
If this topic maps to a real risk in your stack, these are the most relevant CleanIssue audits.