GraphQL Hacking: The Complete Practical Guide
Finding GraphQL Endpoints
How to find a GraphQL endpoint: the common paths, confirming with a trivial query, GraphiQL and Apollo Sandbox tells, and spotting GraphQL in the SPA bundle.
Published
You cannot test a GraphQL API until you find its endpoint, and GraphQL hides behind a small set of conventions. This page covers the paths to probe, how to confirm an endpoint cheaply, and the tells that give it away. Practice on a free live target.
Step 1: probe the common paths
GraphQL is almost always mounted at a conventional path. Try these first:
/graphql /graphiql /graphql/console
/v1/graphql /api/graphql /graphql/v1
/query /index.php?graphql /.netlify/functions/graphqlA path that responds differently from a random 404 (a 400 with a GraphQL error, a 405 method-not-allowed, or an actual data body) is a candidate.
Step 2: confirm with a trivial query
The cheapest confirmation is a query for __typename, a meta-field every GraphQL schema answers:
POST /graphql HTTP/1.1
Host: target.example
Content-Type: application/json
{"query":"{ __typename }"}HTTP/1.1 200 OK
Content-Type: application/json
{"data":{"__typename":"Query"}}A data object with a type name confirms GraphQL. The root type is named Query by convention, though a schema can rename it, so match on "a type name came back", not on the literal word. Even an error body counts if it is GraphQL-shaped:
{"errors":[{"message":"Must provide query string."}]}A generic 404 or an HTML error page means this is not it, so move to the next path.
Step 3: look for the tells
Beyond blind probing, GraphQL often announces itself:
- GraphiQL / GraphQL Playground / Apollo Sandbox: an in-browser IDE at the endpoint usually means introspection is on, which is the jackpot for the next step.
- The SPA bundle: front-end JavaScript frequently hardcodes the endpoint path and even the exact queries. Search the bundle for
/graphql,query,mutation, and__typename. - Response headers and framework fingerprints: Apollo and others sometimes leave tells in headers or error formats.
Edge variants
GET /graphql?query={__typename} some servers answer queries over GET
POST /graphql Content-Type: application/graphql raw-query content type, body is the query itself
/subscriptions or wss://host/graphql subscriptions transport, often a separate pathWordlist discovery (fuzzing a path list against the host) catches the non-standard mounts. If the endpoint answers but __schema is blocked, you are not stuck: see the suggestions route in bypassing introspection defenses.
Fixing it
- Do not expose a GraphQL IDE in production. Disable GraphiQL, Playground, and Sandbox on live endpoints.
- Return consistent, minimal errors. A verbose GraphQL error on every junk request advertises the endpoint.
- Treat the endpoint as authenticated surface, not as something hidden by an unusual path.
Full guidance is in preventing GraphQL attacks. Next, pull the whole schema in introspection and schema discovery, or find an endpoint on a free lab.