SecureBlockLog inStart a pentest
Vulnerability Repository
MediumAPI

GraphQL Introspection Enabled

Enabled GraphQL introspection in production exposes the complete API schema to attackers, revealing all types, queries, mutations, and internal field names.

CVSS 5.3CWE CWE-200OWASP A05:2021 — Security Misconfiguration

Description

GraphQL introspection is a built-in capability that allows clients to query the API's schema—discovering all available types, fields, queries, mutations, and subscriptions. This feature is invaluable during development because it powers tools like GraphQL Playground and Apollo Studio. In production environments exposed to untrusted clients, however, enabled introspection hands attackers a complete map of the API's data model and operations, dramatically accelerating reconnaissance.

CWE-200 applies because the introspection endpoint discloses information about the system's internal structure to unauthorized parties. A05:2021 Security Misconfiguration covers this as a configuration that is appropriate for development but should not be deployed to production. With introspection enabled, an attacker does not need to guess field names or infer schema from observed responses—they can retrieve the complete schema with a single query and immediately identify high-value mutation targets, internal types, and deprecated endpoints that may lack modern security controls.

The issue is compounded by GraphQL's flexibility: a schema may include mutations that create admin users, queries that return all user data, or subscriptions that expose real-time sensitive events. Without introspection, these must be discovered by trial and error. With introspection, they are immediately enumerated.

How It Works

An attacker sends a standard introspection query to the GraphQL endpoint:

POST /graphql HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "query": "{ __schema { types { name fields { name type { name } } } } }"
}

A more complete schema extraction using the standard IntrospectionQuery:

# Using graphql-introspection-query tool or raw curl
curl -s -X POST https://api.example.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{__schema{queryType{name}mutationType{name}types{kind name fields{name args{name type{kind name ofType{kind name}}}type{kind name ofType{kind name}}}}}}"}' \
  | python3 -m json.tool

Tools like GraphQL Voyager visualize the schema as an interactive graph, and graphql-cop automates security testing of the endpoint:

# graphql-cop security audit
python3 graphql-cop.py -t https://api.example.com/graphql

# InQL Burp Suite extension — generates all queries/mutations from schema
# Load the introspection result into InQL to auto-generate test cases

An introspection response might reveal:

{
  "data": {
    "__schema": {
      "mutationType": {
        "name": "Mutation"
      },
      "types": [
        {
          "name": "Mutation",
          "fields": [
            {"name": "createAdminUser"},
            {"name": "deleteAllAuditLogs"},
            {"name": "exportAllUserData"},
            {"name": "resetUserPassword"}
          ]
        }
      ]
    }
  }
}

The attacker now knows to attempt createAdminUser and exportAllUserData mutations, regardless of authorization controls, purely through schema discovery.

Impact

  • Accelerated attack surface mapping — Attackers enumerate all mutations and queries in seconds instead of hours of blind probing.
  • Sensitive field discovery — Internal field names like internalScore, adminNotes, or ssn reveal data that should not be accessible and may be exploitable via BOPLA.
  • Deprecated endpoint targeting — Legacy mutations in the schema may lack modern authorization controls added to newer endpoints.
  • Automated exploit generation — Tools like InQL generate complete sets of test queries from the schema, enabling rapid automated testing of every endpoint.
  • Business logic disclosure — Schema structure reveals internal domain concepts, relationships, and workflows that inform social engineering and business logic attacks.

Detection

  1. Send an introspection query ({ __schema { types { name } } }) to the GraphQL endpoint and verify whether a schema response is returned.
  2. Test introspection from unauthenticated and low-privilege authenticated contexts separately—introspection may be restricted to authenticated users but not to specific roles.
  3. Run graphql-cop to comprehensively test for introspection, batching, field suggestions, and other GraphQL-specific security issues.
  4. Test field suggestion behavior even if introspection is disabled: GraphQL servers often return suggestions like "Did you mean adminEmail?" in error messages, leaking field names.
  5. Check for GraphQL Playground or GraphiQL being served in production—these interactive IDEs typically require and enable introspection.

Remediation

Disable introspection in production. Most GraphQL server libraries provide a configuration option:

// Apollo Server — disable introspection in production
const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== 'production',
  plugins: [process.env.NODE_ENV === 'production' && ApolloServerPluginDisableIntrospection()].filter(Boolean),
});

Disable field suggestions. Alongside introspection, disable field suggestion error messages to prevent schema enumeration through error messages.

Implement query depth and complexity limits. Regardless of introspection status, enforce maximum query depth (typically 5-7 levels) and complexity limits to prevent resource exhaustion via deeply nested queries.

Apply authorization at the resolver level. Every resolver must perform its own authorization check—do not rely on introspection being disabled as a substitute for resolver-level access control.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping