Skip to content

Back to the catalog

Clairvoyance
github.comrepo

Clairvoyance

Clairvoyance is a Python tool that reconstructs a GraphQL API's schema even when introspection is disabled (e.g., Apollo Server in production mode) by brute-forcing field and type names against the API using wordlists. Output is JSON schema compatible with downstream tools like GraphQL Voyager, InQL, and graphql-path-enum, making it useful for API reconnaissance during bug bounty and pentest engagements.

TL;DR CLI/Docker tool that brute-forces GraphQL schemas when introspection is disabled, for API recon and bug bounty work.
Document

What it is

Clairvoyance is a Python CLI that reconstructs a GraphQL schema when introspection is disabled — the default in Apollo Server when NODE_ENV=production. It outputs JSON consumable by GraphQL Voyager, InQL, or graphql-path-enum.

How it works

It brute-forces field and type names against the live endpoint using a wordlist. The page gives three wordlist strategies, in roughly increasing yield:

  • Escape Technologies' collected wordlists.
  • General English words (e.g. google-10000-english).
  • A target-specific wordlist built by extracting every valid GraphQL name from application HTTP traffic, mobile app static files, etc. A valid GraphQL name matches the regex [_A-Za-z][_0-9A-Za-z]*.

The target-specific approach is the one worth the setup effort — the summary mentions it exists, but the page's actual point is that you should harvest names from traffic/binaries with that regex rather than rely on generic lists.

What to do

Install and run:

pip install clairvoyance
clairvoyance https://rickandmortyapi.com/graphql -o schema.json
# should take about 2 minutes

Or via Docker:

docker run --rm nikitastupin/clairvoyance --help

Logging is configurable via environment variables:

LOG_FMT=`%(asctime)s \t%(levelname)s\t| %(message)s`
LOG_DATEFMT=`%Y-%m-%d %H:%M:%S`
LOG_LEVEL=`INFO`

Caveats

Wordlist quality bounds coverage: brute-forcing only recovers names present in the list, so a generic English list will miss custom types and fields. Expect the target-specific extraction step to be necessary for a complete schema. The page cites the second half of Nikita Stupin's talk "GraphQL APIs from bug hunter's perspective" for mechanism detail.

Technologies named here

Techniques named here

  • GraphQL schema reconstruction without introspection
  • Wordlist-based GraphQL name discovery
  • Target-specific wordlist creation