← Todos los checks
SeguridadSeveridad típica: Medio

Introspección de GraphQL

Comprueba si tu endpoint GraphQL revela el esquema completo de la API por tener la introspección activa.

Qué comprueba

Este escáner comprueba si tu endpoint GraphQL tiene la introspección activada, lo que revela el esquema completo de tu API. Detecta cuando cualquiera puede consultar toda la estructura de tipos, campos y operaciones disponibles.

Por qué importa

Con la introspección activa, un atacante obtiene el mapa detallado de tu API sin esfuerzo, incluyendo campos y operaciones internas que quizá no querías mostrar. Ese conocimiento le facilita mucho encontrar puntos débiles y datos que explorar.

Cómo se arregla

Desactiva la introspección de GraphQL en tu entorno de producción, dejándola activa solo en desarrollo. La mayoría de librerías de GraphQL permiten hacerlo con una opción de configuración según el entorno.

Cómo funciona esta comprobación

Scanaris envía una petición POST con la consulta de introspección más pequeña posible, {__schema{queryType{name}}}, a tres rutas donde suele vivir un endpoint GraphQL: /graphql, /api/graphql y /v1/graphql. Si alguna responde 200 y el cuerpo contiene __schema o queryType, la introspección está habilitada y abre un hallazgo de severidad media con la ruta. Si no hay GraphQL en tu web, ninguna ruta responde con eso y no hay hallazgo. La consulta es de solo lectura, no toca datos, y pasa por los mismos límites de tiempo y tamaño que el resto del escaneo.

Por qué importa

La introspección es la función de GraphQL que permite preguntarle a la API por su propio esquema: todos los tipos, todos los campos de cada tipo, todas las consultas y mutaciones disponibles, con sus argumentos. En desarrollo es imprescindible: es lo que usan el playground, el autocompletado del editor y los generadores de código. En producción, abierta a cualquiera, es un mapa completo de tu backend. Un atacante ve que existe una mutación deleteUser(id) o un campo internalNotes sin tener que adivinarlos, y va directo a probar si la autorización de cada uno está bien hecha. Por eso es severidad media: no expone datos por sí misma, pero convierte cualquier otro fallo de permisos en algo trivial de encontrar.

Cómo desactivarla en producción

  • Apollo Server: introspection: "production" !== 'production' al crear el servidor. Desde Apollo 4 ya viene desactivada cuando NODE_ENV es production; si la ves activa, comprueba que esa variable llega a tu despliegue. Desactiva también la landing page o el playground en producción.
  • GraphQL Yoga y Envelop: el plugin useDisableIntrospection() de @envelop/disable-introspection, condicionado al entorno.
  • Hasura (la ruta /v1/graphql): en los ajustes de seguridad del proyecto hay un control de introspección por rol (Cloud y Enterprise). Asegúrate además de que el rol público tiene permisos mínimos y de que el secreto de administrador nunca viaja al navegador.
  • graphql-ruby: disable_introspection_entry_points en la clase del esquema.
  • Python (Graphene, Strawberry, Ariadne): añade la regla NoSchemaIntrospectionCustomRule de graphql-core a las reglas de validación en producción.
  • .NET (Hot Chocolate): .AllowIntrospection(false) o la opción de modificar la introspección por petición según un header o un rol.

Desactivar la introspección no sustituye a la autorización: cada consulta y mutación debe comprobar quién pregunta. Acompáñala de límites de profundidad y complejidad de consulta (evitan consultas anidadas que tumban el servidor) y, si tu servidor lo ofrece, desactiva también las sugerencias de campos ("Did you mean…"), que filtran nombres aunque la introspección esté cerrada.

Comprueba que está arreglado

curl -s -X POST https://tudominio.com/graphql -H "Content-Type: application/json" -d '{"query":"{__schema{queryType{name}}}"}'

Repite con /api/graphql y /v1/graphql. Esperado: un error del tipo "introspection is not allowed", un 400 o 403, o un 404 si no hay GraphQL ahí. Si ves "queryType":{"name":"Query"}, sigue abierta.

Preguntas frecuentes

Mi API es pública y está documentada. ¿Me afecta?

Si publicas el esquema a propósito, la introspección abierta no revela nada nuevo y puedes dar el hallazgo por aceptado. La mayoría de las APIs de aplicaciones no están en ese caso: tienen mutaciones internas que nadie debería conocer.

Mi endpoint está en otra ruta. ¿No se comprueba?

Solo se prueban las tres rutas más comunes. Si el tuyo vive en otra, haz la prueba de arriba con tu ruta real. Otros paneles y endpoints de desarrollo que no deberían responder en producción los busca endpoints expuestos.

¿Y si el endpoint pide autenticación?

Entonces la introspección responde 401 y no se marca. Es la situación correcta: un atacante sin sesión no obtiene el esquema. Comprueba que la cabecera CORS de la API no esté abierta a cualquier origen; eso lo mira CORS permisivo.

Compruébalo en tu web

Escanea tu web gratis y mira si este y otros 44 checks pasan, con un prompt de arreglo por cada fallo.

Escanear mi web gratis

Checks relacionados