GraphQL Introspection Enabled in Production
What Is This Vulnerability?
GraphQL introspection allows clients to query the full schema, revealing every type, field, mutation, and relationship in your API. While useful during development, leaving it enabled in production gives attackers a complete map of your data model. This makes it trivial to find sensitive fields, discover hidden mutations, and craft targeted attacks.
Why It Happens
GraphQL servers enable introspection by default because it powers developer tools like GraphiQL and Apollo Studio. Teams often forget to disable it when deploying to production. Some assume that not documenting the API publicly is sufficient security, not realizing that introspection makes the entire schema self-documenting to anyone who queries it.
Example Code
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
const server = new ApolloServer({
typeDefs,
resolvers,
});
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
});import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== "production",
});
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
});How Hackers Exploit It
Attackers send an introspection query (__schema) to discover the full API surface. They identify sensitive fields like adminNotes, internalId, or deletedUsers that may lack authorization checks. They find mutations for privilege escalation, data modification, or account takeover. The full schema also reveals database structure and business logic through type names and relationships.
How to Fix It
Disable introspection in production by setting the introspection option to false in your GraphQL server configuration. Use field-level authorization to protect sensitive data regardless of schema visibility. Implement query depth limiting and complexity analysis to prevent abuse. Consider using persisted queries to restrict which operations clients can execute.