What is GraphQL Introspection?
GraphQL's introspection feature is a powerful asset for client-side developers, particularly those working on front-end applications. The cornerstone of the GraphQL specification's appeal to web application, lies in its precision—developers can precisely specify and fetch only necessary data by manipulating queries.
Introspection enhances this capability by offering a self-documenting system where developers can explore and understand the various available queries, schema types and available fields above query itself on GraphQL endpoints.
When introspection is removed, developers lose a critical tool that streamlines their workflow generating documentation, and aids in crafting optimized queries. This feature not only boosts developer productivity but also functions as a living documentation system for your own API calls. Without it in production environments, teams often face the additional burden of generating documentation maintaining separate documentation resources.
This parallel documentation effort can introduce new challenges, including the risk of divergence between the actual API implementation and its documentation, while also increasing the overall maintenance complexity.
How to check if GraphQL Introspection is enabled?
Save the following Python script and run it
import requests
def check_introspection(url):
query = '''
{
__schema {
types { name }
}
}'''
print(f"\nTesting GraphQL endpoint: {url}")
print("-" * 50)
try:
resp = requests.post(url, json={'query': query})
if '__schema' in resp.json().get('data', {}):
print("[+] Status: Introspection is ENABLED")
print("[+] Security Risk: The API exposes schema information")
return True
print("[-] Status: Introspection is DISABLED")
print("[+] Security Status: The API is properly secured")
return False
except Exception as e:
print(f"[-] Error: Could not test endpoint ({str(e)})")
return False
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print("Usage: python script.py <graphql_url>")
sys.exit(1)
check_introspection(sys.argv[1])
Run this Python script with the command
python script.py https://api.example.com/graphql
If you see [+] Introspection ENABLED - this means introspection is enabled on the target GraphQL endpoint. If you see [-] Introspection DISABLED - this means it's disabled.
Security Impact
Security concerns stand as the primary rationale for disabling GraphQL introspection in production environments. OWASP also recommends having introspection disabled on its pen testing guidelines. When introspection is enabled, it provides a detailed map of your graphql API's structure, which potential attackers can use to methodically probe for vulnerabilities.
This transparency can inadvertently reveal sensitive operations or endpoints that, while perhaps not explicitly documented, could become attack vectors if discovered.
Performance Implications
Beyond security implications, introspection queries can impact system performance. These queries require the server to perform comprehensive schema traversal and metadata collection, consuming significant computational resources.
This overhead becomes particularly relevant in production environments where system efficiency and response times are critical.
Should I disable GraphQL introspection queries?
While disabling introspection may seem like a security measure, it's largely ineffective. Your GraphQL schema remains discoverable through other means, particularly through Field Suggestion - a feature present in most GraphQL engines.
When queries contain invalid fields, the server's error messages helpfully suggest similar, valid field names, inadvertently revealing schema details.
This makes schema discovery possible even without introspection access.
Disable GraphQL Field Suggestions
For production environments, turn off GraphQL Field Suggestions. This feature should only be left active in development and staging environments where access is controlled.
To disable GraphQL field suggestions (autocompletion), you'll want to disable the GraphQL Playground/GraphiQL interface. Here's how for different frameworks:
Apollo Server:
const server = new ApolloServer({
typeDefs,
resolvers,
playground: false, // Disables entire playground
introspection: false // Also disables field suggestions
});
Express GraphQL:
app.use('/graphql', graphqlHTTP({
schema: schema,
graphiql: false // Disables GraphiQL interface
}));
GraphQL Yoga:
const server = createServer({
schema,
graphiql: false, // Disables GraphiQL
introspection: false // Also prevents field suggestions
});
Django Graphene:
GRAPHENE = {
'SCHEMA': 'myapp.schema.schema',
'GRAPHIQL': False, # Disables GraphiQL interface
'SCHEMA_INTROSPECTION_ENABLED': False
}
Hot Chocolate (.NET):
services
.AddGraphQLServer()
.ModifyOptions(opts => {
opts.EnableSchemaRequests = false;
opts.RemoveIntrospectionTypes = true;
});
Disable GraphQL Introspection
The way to disable GraphQL introspection depends on which GraphQL server/framework you're using. Here are the most common approaches:
Apollo Server:
// In your Apollo Server configuration
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: false // Disable introspection
});
GraphQL Yoga:
const server = createServer({
schema,
graphiql: false,
introspection: false
});
Express-GraphQL:
app.use('/graphql', graphqlHTTP({
schema: schema,
graphiql: false,
introspection: false
}));
GraphQL Java:
GraphQLSchema schema = GraphQLSchema.newSchema()
.query(queryType)
.introspection(false) // Disable introspection
.build();
Django Graphene:
GRAPHENE = {
'SCHEMA': 'myapp.schema.schema',
'SCHEMA_INTROSPECTION_ENABLED': False
}
Hot Chocolate (.NET):
services
.AddGraphQLServer()
.ModifyOptions(opts => opts.RemoveIntrospectionTypes = true);
My Recommendations
Keeping introspection enabled just for staging environments is Cyber Chief's recommended approach since disabling it impedes developer productivity. Consider implementing role-based access control for introspection - for example, limiting it to authenticated developers and administrators rather than disabling it entirely.
While disabling GraphQL introspection in production is generally recommended for security to prevent attackers from discovering API schema details and potential vulnerabilities, some developers argue for keeping it enabled to support client-side development tools and dynamic query building - ultimately requiring teams to balance the tradeoff between developer experience and security posture based on their specific use case and threat model.
GraphQL Introspection Query Techniques
Use the __schema field to discover schema information.
Specify the fields and structure of the response you want to return.
Use introspection queries to piece together information about the underlying schema.
Best Practices for Secure Introspection
Disable Introspection Query in production environments.
Restrict access to introspection queries in production environments.
Keep introspection enabled only in development or staging environments where access is limited to authorized personnel.
Preventing GraphQL Attacks
To prevent many common GraphQL attacks, take the following steps when deploying your API to production:
Disable introspection if your API is not intended for use by the general public.
Review the API’s schema to ensure it does not expose unintended fields to the public.
Disable suggestions.
Make sure the API’s schema does not expose private user fields.
Implementing Introspection Safely
Use a GraphQL visualizer to view relationships between schema entities more easily.
Use suggestions to glean information on an API’s structure, even if introspection is disabled.
Implement rate limiting and configure operation limits to prevent brute force attacks.
How to find & fix vulnerable GraphQL APIs in your app?
Apart from the scripts and guides shared above, you can run scans with a user-friendly web application vulnerability scanning tool, like Cyber Chief, which helps you find critical vulnerabilities in your GraphQL API's, test GraphQL APIs and thousands more.
Watch the Cyber Chief on-demand demo to see not only how it can help to keep attackers out, but also to see how you can ensure that you ship every release with zero known vulnerabilities.
Cyber Chief has been built to integrate with the workflows of high-growth SaaS teams and that's why it offers:
Results from scanning your application for the presence of OWASP Top 10 + SANS CWE 25 + thousands of other vulnerabilities.
A detailed description of the vulnerabilities found.
A risk level for each vulnerability, so you know which ones to fix first.
Best-practice fixes for each vulnerability, including code snippets where relevant.
On-Demand Security Coaching from our application security experts to help you patch vulnerabilities in hours, not days.
Which option do you prefer?
Click the green button below to see how Cyber Chief works.