GraphQL Misconfiguration
What it is
A GraphQL endpoint exposing more than it should — introspection left enabled in production, revealing the entire schema, or mutations that skip authorization checks their REST equivalents would enforce.
Why it matters
One query can enumerate the entire internal data model — types, fields, relationships — turning what would take days of REST endpoint discovery into a single request.
Where to look
- Common paths:
,/graphql
,/api/graphql
,/gql/v1/graphql
How I test it
- Find the GraphQL endpoint.
- Send a simple query to confirm it responds.
- Check introspection:
— if this returns data, the whole schema is enumerable.{ __schema { types { name } } } - Enumerate types and mutations from the schema, looking for anything sensitive by name (user, admin, billing, internal).
- Test with two accounts: does a query let account B read account A's data by ID (GraphQL IDOR)? Does a mutation let a normal account perform an action it shouldn't?
Hunting checklist
- Found the GraphQL endpoint
- Tested introspection
- Enumerated the schema for sensitive types/fields
- Tested IDOR-style access through queries with two accounts
- Tested unauthorized mutations with a normal account
Evidence to collect
- The introspection query and its full response
- A query/mutation proving unauthorized read or write access
- Explanation of which internal structures/data were exposed
Recommended fix
- Disable introspection in production
- Apply the same authorization checks to GraphQL resolvers that REST endpoints would enforce — per field, not just per endpoint
- Rate-limit and depth-limit queries to prevent enumeration and abuse
Qué es
Un endpoint GraphQL que expone más de lo que debería — introspection dejado activo en producción, revelando el schema entero, o mutations que se saltan las comprobaciones de autorización que sí tendría su equivalente REST.
Por qué importa
Una sola query puede enumerar todo el modelo de datos interno — tipos, campos, relaciones — convirtiendo lo que llevaría días de descubrimiento de endpoints REST en una única petición.
Dónde buscar
- Rutas habituales:
,/graphql
,/api/graphql
,/gql/v1/graphql
Cómo lo pruebo
- Encuentra el endpoint GraphQL.
- Envía una query simple para confirmar que responde.
- Comprueba introspection:
— si esto devuelve datos, todo el schema es enumerable.{ __schema { types { name } } } - Enumera tipos y mutations a partir del schema, buscando algo sensible por nombre (user, admin, billing, internal).
- Prueba con dos cuentas: ¿una query permite que la cuenta B lea datos de la cuenta A por ID (IDOR en GraphQL)? ¿Una mutation permite que una cuenta normal haga algo que no debería?
Checklist de hunting
- Encontrado el endpoint GraphQL
- Probado introspection
- Enumerado el schema buscando tipos/campos sensibles
- Probado acceso tipo IDOR vía queries con dos cuentas
- Probadas mutations no autorizadas con cuenta normal
Evidencias para el reporte
- La query de introspection y su respuesta completa
- Una query/mutation que demuestre lectura o escritura no autorizada
- Explicación de qué estructuras/datos internos quedaron expuestos
Mitigación
- Desactivar introspection en producción
- Aplicar a los resolvers de GraphQL las mismas comprobaciones de autorización que tendría un endpoint REST — por campo, no solo por endpoint
- Limitar rate y profundidad de las queries para evitar enumeración y abuso