mediumInfrastructure

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

Vulnerableserver.ts
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 },
});
Fixedserver.ts
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.

Frequently Asked Questions

How do I test if introspection is enabled?
Send a POST request to your GraphQL endpoint with the query '{ __schema { types { name } } }'. If you receive a response listing all types, introspection is enabled. Tools like GraphQL Voyager and InQL can also detect and visualize exposed schemas.
Is disabling introspection enough to secure my GraphQL API?
No. Disabling introspection is one layer of defense, but attackers can still discover fields through error messages and trial-and-error. You must also implement authentication, field-level authorization, query depth limits, rate limiting, and input validation to properly secure a GraphQL API.
Should I disable introspection in staging environments?
Keep introspection enabled in development and staging environments where developers and QA need it. Only disable it in production. Use environment variables to toggle the setting so the same codebase works across environments without code changes.

Related Security Topics

Check Your Code for This Vulnerability

Run a free scan to check if your site is affected by graphql introspection enabled in production.