Skip to main content

gqlhunter

GraphQL recon & analysis CLI — find endpoints, dump schema, flag risky fields.
detection-only · scope-aware · bug-bounty ready

CI PyPI License Stars

🌍 bess1lie.github.io · 🔍 apihunter · 🎯 bounthunt


📦 Installation

# From PyPI (recommended) — detection-only, scope-aware
pip install gqlhunter
gqlhunter --help

# Isolated with pipx (recommended for tools)
pipx install gqlhunter

# From source (latest dev)
git clone https://github.com/bess1lie/gqlhunter.git
cd gqlhunter
pip install -e ".[dev]"

⚡ 30-second start

pip install gqlhunter   # or pipx install gqlhunter
# 1. scope — allowlist for your target (never scan out-of-scope)
cat > scope.yaml <<'YAML'
targets: ["https://example.com"]
allowlist: ["example.com"]
YAML

# 2. discover + scan + risk in one go
gqlhunter discover https://example.com --scope scope.yaml
gqlhunter scan https://example.com/graphql --scope scope.yaml

# 3. report + dashboard
gqlhunter report --db gqlhunter_*.db --format html -o report.html
gqlhunter dashboard --db gqlhunter_*.db
# -> http://127.0.0.1:8080

Why now: 46k GraphQL issues found across 1500 APIs in 2024, 10% critical (Escape Tech). Introspection + batching + depth misconfigs are still the top 3.


✨ Features

Feature What it does Output
Discovery 18 common paths + POST fallback live endpoints
Introspection Configurable depth, handles REQUIRES_AUTH/FILTERED __schema
Risk delete*/admin*/reset* + IDOR args (id, email, uuid) critical/high/medium/low
Auth With vs without token, body-aware (Unauthorized in 200) public/auth_required/over_permissive
Diff Schema changes across 2 runs added/modified/removed
Variants alias, arg-removal, depth query templates
Export JSON clean + SARIF 2.1.0 gqlhunter.sarif for Code Scanning
Notify Slack / Telegram / Webhook via Jinja notify
Dashboard SQLite + built-in HTTP UI /api/runs

🚀 Demo

discover + scan report + dashboard
$ gqlhunter discover https://example.com --scope scope.yaml
╭────────── Discovered ──────────╮
│ https://example.com/graphql 200 │
│ https://example.com/graphiql 200 │
╰──────────────────────────────╯

$ gqlhunter scan https://example.com/graphql --scope scope.yaml
Introspection: enabled (HTTP 200)
Stored 18 types, 8 queries, 3 mutations
Risk findings: 2 high, 1 medium
dashboard
report

📖 Commands

Command Purpose Example
discover Find GraphQL endpoints gqlhunter discover https://example.com --scope scope.yaml
scan Introspection + risk (single endpoint) gqlhunter scan https://example.com/graphql --scope scope.yaml --max-depth 5
batch Multi-target from scope.yaml gqlhunter batch scope.yaml --db batch.db
auth Token vs anon comparison gqlhunter auth https://example.com/graphql --scope scope.yaml --auth-header "Bearer x" --db scan.db
variants Query variant generation gqlhunter variants --db scan.db --strategy combinations
report HTML / Markdown gqlhunter report --db scan.db -o report.html
export JSON + SARIF gqlhunter export --db scan.db --output out/ --sarif
diff Last 2 runs diff gqlhunter diff --db batch.db
notify Slack/TG/webhook gqlhunter notify slack --db scan.db --webhook-url https://hooks.slack.com/...
dashboard Web UI gqlhunter dashboard --db scan.db

Full docs: docs/scope.md · docs/examples.md · docs/notifications.md


🏗️ Architecture

flowchart LR
    T[Target] --> D[Discovery 18 paths + POST]
    D --> I[Introspection]
    I --> P[Parser]
    P --> A[Risk IDOR+BOLA]
    P --> Q[Query Builder]
    P --> U[Auth Analyzer]
    A --> DB[(SQLite)]
    Q --> DB
    U --> DB
    DB --> R[Report HTML/MD]
    DB --> E[Export SARIF]
    DB --> V[Dashboard]
    DB --> N[Diff/Notify]

Stack: Python 3.11+ · Typer · httpx (+sse) · SQLite (WAL) · Jinja2 · Docker


🛡️ Philosophy

🔍 Detection only — never payloads, never exploitation
🛡️ Scope-aware — every request gated by scope.yaml
📂 Open formats — SQLite, HTML, SARIF 2.1.0
🧪 202 tests in CI

🗺️ Roadmap

Feature Status
Discovery (18 paths + POST)
Introspection + risk + IDOR
Auth body-aware (200+errors)
Dashboard + diff + SARIF
Batching amplification tester 🚧 next
Depth/Complexity DoS tester 🚧
Clairvoyance (introspection off) 🔮
WebSocket subscriptions 🔮

❓ FAQ

Does it exploit? No. It discovers and classifies. Variant queries include # DO NOT AUTO-RUN warning.

Introspection disabled? Marked FILTERED/DISABLED. Next: Clairvoyance-lite via Did you mean ...? reconstruction.

Scope required? Yes. scope.yaml with targets/allowlist is mandatory for discover/scan/batch.

SARIF upload? gqlhunter.sarif → GitHub Code Scanning. Version synced from __version__.


🤝 Contributing

git clone https://github.com/bess1lie/gqlhunter.git
cd gqlhunter
pip install -e ".[dev]"
pytest -q  # 202 tests
ruff check gqlhunter/ && ruff format --check gqlhunter/
pip install gqlhunter  # try published package smoke test

See CONTRIBUTING.md if present, else open an issue.

📄 License

MIT — see LICENSE.


built in Almaty · bess1lie · detection-first security tooling

Star History

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gqlhunter-0.3.0.tar.gz (207.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gqlhunter-0.3.0-py3-none-any.whl (40.8 kB view details)

Uploaded Python 3

File details

Details for the file gqlhunter-0.3.0.tar.gz.

File metadata

  • Download URL: gqlhunter-0.3.0.tar.gz
  • Upload date:
  • Size: 207.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for gqlhunter-0.3.0.tar.gz
Algorithm Hash digest
SHA256 20ea1922a3b02e0512bb2d4cb1a9c8e7e75a8a7a46fe47c7b0477a0240996a8c
MD5 40fa346ed09e442b7e6007b4b2c7ed12
BLAKE2b-256 cfb376c105b4a8b381baf93a59b97caa32b8717aa9f09fa1097a7b4d03be4040

See more details on using hashes here.

File details

Details for the file gqlhunter-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: gqlhunter-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 40.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for gqlhunter-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 26145f76827fd582e4e3cd2ccfa19a72388a57b5159ca4b58df7d233cbc174bb
MD5 cb3186ea972d220bb4d5a5e4ff46c0fb
BLAKE2b-256 d53edf1b27b99d9f6ddf2a702ffee9e1138b2929ba1086cc8c9c799d73f4370d

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page