GraphQL API: 6 vulnerabilities that scanners don't detect
> TL;DR: Introspection enabled, depth attacks, batching, IDOR via relay IDs — GraphQL flaws invisible to automated tools.
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.
Key Takeaways
Building HR, payroll, or recruiting software? CleanIssue performs security audits for HR SaaS in real-world conditions, no source code access needed. For a first read of your exposure, start with an external review of your application.
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.
User enumeration: how your API reveals who your customers are
Differentiated error messages, sequential IDs, endpoints without rate limiting: your API may allow listing your customers and their employees. Why it matters for HR SaaS, and how to fix it.
JWT token management in HR SaaS: pitfalls to avoid
JSON Web Tokens are everywhere in modern SaaS. But poor expiration and rotation management can compromise your entire application.
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.