Skip to main content

Introspection enabled

Description

GraphQL introspection enables you to query a GraphQL server for information about the underlying schema, including data like types, fields, queries, mutations, and even the field-level descriptions. It discloses sensitive information that potentially allows an attacker to design malicious operations.

Remediation

Introspection should primarily be used as a discovery and diagnostic tool when we're in the development phase of building out GraphQL APIs. While it's still possible for bad actors to learn how to write malicious queries by reverse engineering your GraphQL API through a lot of trial and error, disabling introspection is a form of security by obscurity.

GraphQL Specific

Apollo

To disable Introspection, either set NODE_ENV to production or enforce it :

const server = new ApolloServer({
typeDefs,
resolvers,
introspection: false
});

Source: https://escape.tech/blog/9-graphql-security-best-practices/

Ariadne

When defining the ariadne.asgi.GraphQL app make sure to add the flag introspection=False

Awsappsync

Add ACL rule to prevent GraphQL schema introspection queries to the API. This is achieved by blocking any HTTP body that includes the string "schema". This would be entered into the Rule JSON editor when creating a web ACL in the AWS WAF Console.

{
"Name": "Block-Introspection",
"Priority": 5,
"Action": {
"Block": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "Block-Introspection"
},
"Statement": {
"ByteMatchStatement": {
"FieldToMatch": {
"Body": {}
},
"PositionalConstraint": "CONTAINS",
"SearchString": "__schema",
"TextTransformations": [
{
"Type": "NONE",
"Priority": 0
}
]
}
}
}

Don't forget to associate the previously created ACL rule with your AppSync API.

For more information refer to :

AWS AppSync - Developer Guide

Integrate an AppSync API with AWS WAF

AWS Web Application Firewall

Graphene

When using Graphene, here is how you would disable introspection for your schema.

from graphql import validate, parse
from graphene import ObjectType, Schema, String
from graphene.validation import DisableIntrospection


class MyQuery(ObjectType):
name = String(required=True)


schema = Schema(query=MyQuery)

# introspection queries will not be executed.

validation_errors = validate(
schema=schema.graphql_schema,
document_ast=parse('THE QUERY'),
rules=(
DisableIntrospection,
)
)

Source: docs.graphene-python.org

Graphqlgo

graphql-go/graphql does not allow you to disable Introspection.

However, you can disable it with a custom middleware filtering the keyword __schema:


func blockIntrospection(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
bodyBytes, _ := ioutil.ReadAll(r.Body)
r.Body.Close()
r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
body_lower := bytes.ToLower(bodyBytes)
subslice := "__schema"
if bytes.Contains(body_lower, []byte(subslice)) {
no_introspection := "{\"errors\": [{\"message\": \"Introspection is disabled.\"}],\"data\": null}"
w.Write([]byte(no_introspection))
} else {
next.ServeHTTP(w, r)
}
})
}

...

func main(){
...
h := handler.New(...) // GraphQL handler

http.Handle("/graphql", blockIntrospection(h))

}
Graphqljava
GraphQLSchema schema = GraphQLSchema.newSchema()
.query(StarWarsSchema.queryType)
.fieldVisibility( NoIntrospectionGraphqlFieldVisibility.NO_INTROSPECTION_FIELD_VISIBILITY )
.build();

Source: https://www.graphql-java.com/documentation/v11/execution/

Graphqlphp
use GraphQL\GraphQL;
use GraphQL\Validator\Rules\DisableIntrospection;
use GraphQL\Validator\DocumentValidator;
DocumentValidator::addRule(new DisableIntrospection());<code>
</code>

Source: https://webonyx.github.io/graphql-php/security/#disabling-introspection

Hasura

Hasura allows you to control who can run an introspection query.

To do so:

  • Go to Project Console > Security Settings > Schema Introspection
  • Select a role (e.g., guest)
  • Check "Disabled"

See the official guide for more information.

Ruby
class MySchema < GraphQL::Schema
disable_introspection_entry_points if Rails.env.production?
end

Source: https://github.com/rmosolgo/graphql-ruby/blob/master/guides/schema/introspection.md#disabling-introspection

Configuration

Identifier: information_disclosure/introspection_enabled

Examples

Ignore this check

{
"checks": {
"information_disclosure/introspection_enabled": {
"skip": true
}
}
}

Score

  • Escape Severity: INFO
    • OWASP: API7:2023
    • PCI DSS: 6.5.8
    • CWE
    • WASC: WASC-15

CVSS

  • CVSS_VECTOR: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N/E:F/RL:O/RC:C
  • CVSS_SCORE: 4.9

References