Introspection GraphQL publique : pourquoi c'est un problème et comment la désactiver
L'introspection GraphQL est la requête intégrée qui renvoie le schéma complet de votre API : chaque type, champ, argument et mutation. Elle est indispensable en développement, mais ne devrait pas être accessible en production pour une API privée. Laissée active, c'est une carte de toute la surface d'attaque de votre backend.
Ce que c’est
Chaque serveur GraphQL implémente un petit ensemble de méta-champs, notamment __schema et __type. Un seul POST vers /graphql avec `query { __schema { types { name fields { name } } } }` renvoie la définition complète des types.
Des outils comme GraphiQL, Apollo Sandbox et l'interface Playground s'appuient sur l'introspection pour l'autocomplétion des requêtes et l'affichage de l'explorateur de schéma. En développement, c'est ce que vous voulez ; en production, sur une API privée, cela signifie que n'importe qui dans le monde peut télécharger la même carte.
Pourquoi ça compte
Le schéma nomme vos modèles, vos relations et chaque mutation que vous exposez — y compris les champs d'administration, internes et dépréciés qui n'étaient pas censés être découverts depuis l'extérieur. Les attaquants s'en servent pour dresser une liste ciblée d'opérations à sonder à la recherche de contournements d'authentification, d'IDOR et de failles d'injection.
Même si chaque champ est correctement autorisé, des mutations cachées comme refundOrder, impersonateUser ou exportBackup ne devraient pas s'afficher d'elles-mêmes. L'introspection transforme la phase de reconnaissance d'un attaquant, qui passe de plusieurs heures de devinettes à une seule requête.
Comment corriger
Désactivez l'introspection lorsque NODE_ENV vaut production. Laissez-la active en local pour que votre équipe puisse continuer à explorer le schéma dans le Sandbox.
import { ApolloServer } from "@apollo/server";
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== "production",
});Yoga propose un plugin dédié ; graphql-http expose une règle de validation issue de graphql-js. Les deux bloquent les requêtes d'introspection avant leur exécution.
// GraphQL Yoga
import { createYoga } from "graphql-yoga";
import { useDisableIntrospection } from "@graphql-yoga/plugin-disable-introspection";
export const yoga = createYoga({
schema,
plugins: process.env.NODE_ENV === "production" ? [useDisableIntrospection()] : [],
});
// graphql-http (or express-graphql)
import { NoSchemaIntrospectionCustomRule } from "graphql";
const validationRules = process.env.NODE_ENV === "production"
? [NoSchemaIntrospectionCustomRule]
: [];GraphiQL, Playground et Apollo Sandbox servent à aider des humains à explorer le schéma — ils n'ont pas leur place sur un endpoint de production public. Protégez-les par une vérification d'authentification ou ne les montez pas du tout dans le build de production.
Désactiver l'introspection est une mesure de durcissement, pas un contrôle d'accès. Chaque champ a toujours besoin d'une autorisation correcte au niveau du resolver — sinon, quiconque devine un nom de champ peut encore l'appeler. Considérez l'introspection comme une couche de défense parmi d'autres, pas comme la seule.
FAQ
Cacher le schéma, n'est-ce pas simplement de la sécurité par l'obscurité ?
En partie, oui — un attaquant déterminé peut toujours deviner les noms de champs par force brute. Mais rendre la reconnaissance moins facile et moins complète en vaut la peine. Tous les guides d'API GraphQL commerciales et l'OWASP GraphQL Cheat Sheet recommandent de désactiver l'introspection en production.
Et pour une API publique dont je veux que les développeurs explorent le schéma ?
Publiez le schéma de façon délibérée — diffusez un fichier Schema Definition Language, hébergez un site de documentation ou n'exposez l'introspection qu'après authentification. C'est très différent d'un POST anonyme qui renvoie tout.
Comment AppSafe détecte-t-il ce problème ?
AppSafe envoie en POST une petite requête d'introspection vers /graphql et /api/graphql et recherche une réponse __schema avec un statut 200. Si elle revient, le problème est signalé avec une sévérité moyenne dans la catégorie Sécurité des API.
Votre app est-elle concernée ?
AppSafe détecte ce problème et des dizaines d’autres en un seul scan gratuit.
Scanner mon app gratuitementGuides liés
CORS mal configuré : les pièges du joker et du reflet
Autorisez toutes les origines et n’importe quel site peut lire votre API.
Pages d'erreur verbeuses et stack traces en production
Une stack trace indique aux attaquants exactement où viser.
Méthodes HTTP dangereuses : comment TRACE, PUT et DELETE sont annoncées
Une réponse OPTIONS qui liste TRACE ou DELETE révèle plus que nécessaire.
API keys exposées dans le JavaScript côté client
Tout ce qui est dans votre bundle est public. Traitez-le comme tel.