Blog · E.05 · Technical Deep-dive

GraphQL penetration testing: attack surface and method

GraphQL trades REST's many endpoints for a single, hyper-flexible one — and that flexibility, so loved by developers, is exactly what changes the security picture. A tester who treats a GraphQL API like a REST one will miss the flaws that make GraphQL distinctive.

GraphQLAPI SecurityIntrospectionBOLAQuery DoS
GraphQL Surface: Introspection · Nested-query DoS · BOLA / Field Auth · Batching & Aliasing (rate-limit bypass) · Injection · Verbose Errors GraphQL Surface: Introspection · Nested-query DoS · BOLA / Field Auth · Batching & Aliasing (rate-limit bypass) · Injection · Verbose Errors
// TL;DR

GraphQL exposes a single endpoint with a flexible query language, so the attack surface differs from REST. Testing focuses on: introspection revealing the whole schema; nested/recursive queries causing denial of service; broken object- and field-level authorisation (BOLA) across related objects; batching and aliasing that bypass rate limits and brute-force protections; injection through resolver arguments; and verbose errors leaking internals. The usual web and authorisation risks still apply, but GraphQL adds these query-language-specific issues — and, as ever, the highest-impact findings are often business-logic abuse of mutations that no scanner catches.

// 01 Why GraphQL changes the picture

A REST API spreads its functionality across many endpoints, each with fixed responses. GraphQL collapses that into one endpoint where the client decides exactly what data to fetch, across arbitrarily deep relationships, in a single request. That design is powerful — and it shifts risk. The server can no longer reason about a request as a simple "GET /users/123"; it must resolve a client-defined graph of fields, each of which needs its own authorisation and cost control. Testing GraphQL means probing that resolution: what the schema reveals, how deep a query can go, and whether every field checks who's asking.

// 02 The GraphQL attack surface

01

Introspection

GraphQL can describe its own schema. If introspection is exposed, an attacker downloads the entire API map — every type, field and mutation — in one query.

02

Nested-query DoS

Deeply nested or recursive queries make the server resolve enormous data from one request — a resource-exhaustion denial of service unique to GraphQL.

03

Broken authorisation

BOLA and missing field-level checks let users read objects and fields they shouldn't — easy to miss across many related types.

04

Batching & aliasing

Multiple operations in one request, or aliased duplicate fields, can bypass rate limiting and brute-force protection — e.g. thousands of login attempts in one call.

05

Injection

Resolver arguments feed backends, so SQL, NoSQL and command injection reach through GraphQL just as through any input.

06

Verbose errors

Default error handling can leak stack traces, backend details and schema hints that accelerate an attack.

// 03 How testers assess it

A GraphQL test follows a repeatable arc. First, map the schema — via introspection if it's open, or by inference if it's not. Then work through the surface: attempt deep and aliased queries to gauge depth and cost limits; test authorisation by requesting objects and fields as different users; abuse batching to bypass rate limits on sensitive operations like login and password reset; push malicious input through resolver arguments to find injection; and read error responses for leaked internals. Throughout, the mutations get special attention, because that's where business-logic abuse of the actual application lives. This sits inside our broader API penetration testing, mapped to the OWASP API Security Top 10 and the OWASP testing guides.

// 04 How to secure a GraphQL API

// 05 Frequently asked questions

How is GraphQL testing different from REST?

GraphQL exposes a single endpoint with a flexible query language, so testers focus on introspection (full-schema exposure), nested-query DoS, broken object/field authorisation, batching/aliasing that bypass rate limits, and injection through arguments — on top of the usual web and authorisation risks.

What are the main GraphQL vulnerabilities?

Exposed introspection, nested/recursive query DoS, broken object- and field-level authorisation, batching and aliasing that bypass rate limits, injection through resolver arguments, and information disclosure via verbose errors. Business-logic abuse of mutations is a frequent high-impact finding.

Should introspection be disabled in production?

Generally yes for public APIs — it hands attackers a full map of the schema. It's defence in depth, not a replacement for authorisation, since a determined attacker can often infer the schema. Combine it with strict authorisation and depth/complexity limits.

How do you prevent GraphQL denial of service?

Use query depth limiting, complexity/cost analysis to reject expensive queries, pagination limits, timeouts, and rate limiting that accounts for batched operations. Without these, one crafted nested query can exhaust server resources.

// 06 References

UG

Usama Gul

Founder & Penetration Testing Lead, CyberFortify

Tests GraphQL and REST APIs across the GCC, focusing on the authorisation and query-cost flaws that GraphQL's flexibility introduces and that scanners overlook.

Running a GraphQL API?

We test GraphQL the way it actually breaks — introspection, query-cost DoS, field-level authorisation and batching abuse — mapped to the OWASP API Security Top 10, with fixes your engineers can action.

Scope an API test → API testing service →