GraphQL Introspection Enabled
ID |
graphql_introspection_enabled |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Family |
API8:2023 - Security Misconfiguration |
CWE |
CWE-200 |
Resource |
configuration |
Language |
any |
Description
Fires once per GraphQL service when the project constructs a GraphQL server but shows no evidence that schema introspection is disabled — Apollo introspection: false, GraphQL.js NoSchemaIntrospectionCustomRule, graphql-yoga useDisableIntrospection, graphql-java NoIntrospectionGraphqlFieldVisibility, Spring GraphQL introspection.enabled: false, Hot Chocolate .DisableIntrospection(), Strawberry DisableIntrospection, or a GraphQL Armor bundle.
Surfaced as an advisory posture finding: introspection may be gated per environment (env var, feature flag) or blocked at the gateway in ways static analysis cannot see. SDL-only repositories (schema files without server construction) are not flagged — the runtime posture is unknowable there.
Rationale
Most GraphQL servers enable introspection by default. An introspectable production endpoint hands an attacker the complete schema — every type, field, argument, mutation and deprecated operation — eliminating the reconnaissance cost that REST attackers must pay endpoint by endpoint. Combined with BOLA-style probing or resource-consumption attacks, the schema is the map of exactly what to hit. OWASP API8:2023 — Security Misconfiguration (CWE-200, Exposure of Sensitive Information).
Remediation
Disable schema introspection in production while keeping it available in development:
-
Apollo Server:
new ApolloServer({ introspection: process.env.NODE_ENV !== 'production' }) -
GraphQL.js: add
NoSchemaIntrospectionCustomRuletovalidationRules -
graphql-yoga: register the
useDisableIntrospection()plugin -
graphql-java:
GraphqlFieldVisibility.NO_INTROSPECTION_FIELD_VISIBILITY -
Spring GraphQL:
spring.graphql.schema.introspection.enabled: false -
Hot Chocolate:
.DisableIntrospection()/.AllowIntrospection(false) -
Strawberry:
extensions=[DisableIntrospection]
Alternatively adopt GraphQL Armor, which disables introspection and adds depth/cost guards in one bundle.