Exploring and investigating the vulnerabilities of a GraphQL implementation requires a combination of manual testing, automated tools, and understanding of both GraphQL’s specification and the underlying application stack (backend language, framework, database). Below are 50 in-depth tasks, organized into categories, that you should consider during your GraphQL security assessment.
🛠️ RECONNAISSANCE
-
Locate the GraphQL endpoint Common paths:
/graphql
,/gql
,/api/graphql
. -
Determine the HTTP methods allowed Usually
POST
, sometimesGET
. Misconfigured servers may allow dangerous methods. -
Fingerprint the GraphQL engine/framework E.g., Apollo Server, Graphene, express-graphql, etc., by checking response headers, error messages, or introspection output.
-
Check for introspection availability Query using
__schema { types { name } }
to see if schema introspection is enabled. -
Determine if GraphiQL or GraphQL Playground is exposed Access to these UIs can aid attackers by providing autocomplete and docs.
-
Check for rate-limiting or throttling Send multiple queries or batched requests to determine limits.
-
Assess authentication requirements Can you access the endpoint anonymously?
-
Determine if CORS policy is permissive Misconfigured CORS could allow cross-origin exploitation.
-
Check HTTP headers (security-related)
Cache-Control
,Content-Type
,X-Frame-Options
,CSP
, etc. -
Look for debug info in error messages Stack traces, SQL queries, file paths.
🔍 SCHEMA ENUMERATION
-
Use introspection to dump full schema Use tools like
graphql-voyager
,InQL
, orGraphQL Voyager
. -
Identify object types and input types Understanding data structure is crucial for injection attacks.
-
Enumerate mutations and queries Look for dangerous operations like
create
,update
,delete
. -
Check for custom scalars (e.g., Email, URL, JSON) These might have lenient or flawed validation logic.
-
Check for file upload endpoints (
Upload
scalar) These may expose arbitrary file write vulnerabilities. -
Identify nested types and relationships Useful for crafting deep queries (e.g., for DoS).
-
Analyze directive usage E.g.,
@include
,@skip
, and custom directives. -
Search for deprecated fields May still be functional but unmaintained/insecure.
-
Map out access control annotations E.g.,
@auth
,@admin
,@private
. -
Compare schemas for different user roles Use various tokens to compare visibility.
⚙️ INPUT VALIDATION / INJECTION TESTING
-
Test for GraphQL Injection Inject into fields/variables: Example:
query { user(id: "1) { id name }") }
-
Test for classic SQL injection via GraphQL E.g.,
{ user(id: "1' OR '1'='1") { id } }
-
Test for NoSQL injection (MongoDB/DocumentDB) E.g., passing JSON-like structures into parameters.
-
Check for command injection in mutation fields
-
Try broken input types E.g., sending string where int is expected.
-
Fuzz all input arguments and variables Use fuzzing tools with wordlists for edge-case handling.
-
Try bypassing validation using aliases GraphQL supports field aliases. Use them to craft confusing or deceptive queries.
-
Check for over-permissive enums Some may expose internal application states or modes.
-
Manipulate complex input types (InputObject, Lists) Submit malformed arrays or nested objects.
-
Check for HTTP Parameter Pollution in query variables
🔐 AUTHORIZATION / ACCESS CONTROL
-
Test access control on all queries and mutations Remove JWT, use lower-privileged roles.
-
Access other users’ data via IDOR E.g.,
{ user(id: 2) { email } }
-
Try unauthorized role mutation (e.g., promote to admin)
-
Check object-level access control (OLAC) Nested queries may bypass top-level ACL.
-
Tamper with JWT (alg:none, expired token, etc.)
-
Check if permissions are enforced on resolvers Look for field-level permission leaks.
📉 DOS / ABUSE
-
Perform a query depth attack Deeply nested query to exhaust backend recursion limits.
-
Send large batched queries GraphQL allows batching multiple queries in a single request.
-
Exploit alias overloading Use many aliases to repeat the same field hundreds of times.
-
Send large query payloads to stress parsing
-
Try cyclic queries (fragments referencing each other) Some servers may not properly handle recursion.
-
Check for logging DoS (via verbose queries)
📦 MISC / MISCONFIGURATION
-
Test CSRF if GraphQL is accessible over GET
-
Check for file uploads vulnerabilities (if supported) Abuse
Upload
scalar to try overwriting or injecting. -
Try SSRF via user-supplied URLs in inputs
-
Check if subscriptions are enabled (WebSockets) Misused subscriptions can lead to info leaks or persistent sockets.
-
Abuse query complexity limits Test if
@complexity
directives or query limits are enforced. -
Check if deprecated operations are still active
-
Check GraphQL federation or remote schemas Misconfigured federated services can leak internal APIs.
-
Inspect implementation source code (if available) Look for resolver-level flaws, custom directives, access control logic.
🧰 Tools to Aid in the Assessment
- InQL (Burp plugin + CLI)
- GraphQL Voyager
- GraphQLMap
- GraphBreaker
- [Altair/Insomnia/Postman GraphQL Clients]
- Custom Python scripts using
requests
+graphql-core
orgql