# graphw00f: fingerprinting GraphQL endpoints

> How to install and run graphw00f, what the GraphQL engine tells you about likely weaknesses, and where it fits in Tandera recon.

`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

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

## Core commands

```bash
# 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.

---

Canonical: https://tandera.io/tools/graphw00f
This page as markdown: https://tandera.io/tools/graphw00f.md
Index for agents: https://tandera.io/llms.txt

Every page here is also available as markdown: append `.md` to the path (e.g. `/recon.md`, `/index.md` for this homepage, `/blog/<slug>.md`), or request the canonical path with `Accept: text/markdown`.
