graphw00f: fingerprinting GraphQL endpoints

graphw00f · BSD-3-Clause

graphw00f fingerprints GraphQL servers. It sends a handful of engine-specific queries and, from the error and response behaviour, identifies which GraphQL implementation is running — Apollo, Hasura, graphql-ruby, and dozens more. Knowing the engine tells you which weaknesses to look for, because introspection defaults, batching behaviour and error verbosity vary by implementation.

Install

git clone https://github.com/dolevf/graphw00f.git
cd graphw00f && pip install -r requirements.txt
python main.py -h

Core commands

# detect a GraphQL endpoint, then fingerprint it
python main.py -d -f -t https://example.com/graphql

# supply the endpoint directly
python main.py -f -t https://example.com/api/graphql

# with headers
python main.py -f -t https://example.com/graphql 
  -H "Authorization: Bearer TOKEN"

# list what it can identify
python main.py -l

-d runs detection (finding the endpoint), -f runs fingerprinting (identifying the engine).

Output

[*] Found GraphQL at https://example.com/graphql
[*] Discovered GraphQL Engine: (Apollo)
[!] Attack Surface Matrix: https://github.com/nicholasaleks/graphql-threat-matrix

Where it sits in Tandera

graphw00f runs in the analyze phase of recon_web_lite. It is safe for the NonIntrusive flow because fingerprinting is a small number of benign queries. When it identifies an engine, it establishes context the rest of the assessment uses — a GraphQL endpoint is a different attack surface from REST, and the engine determines which parts of it are exposed by default.

Using it in a pentest

The engine maps to a known weakness set. Once you know it is Apollo versus Hasura, the GraphQL Threat Matrix tells you the default behaviours to check — introspection, field suggestions, batching, depth limiting. Fingerprinting turns a generic “test the GraphQL” into a specific checklist.

Introspection is the first thing to check. If it is enabled, you have the full schema — every type, query and mutation, including administrative ones the UI never calls. That is your map for everything after.

Batching enables attacks the rate limiter does not see. Some engines let you send many operations in one request. If login is a mutation, query batching can turn one HTTP request into hundreds of password attempts under a single rate-limit count. Check whether the identified engine allows it.

early access

Get Tandera before your next engagement.

Join the waitlist for early access. We are onboarding pentest teams in waves.

Priority onboarding for pentest teams.
A direct line to the people building it.
Early-access pricing, locked in.

No spam, no card. Unsubscribe anytime.

enespt-br