This vulnerability exposes information about all the APIs available on a GraphQL
API server. This information can be used to discover weaknesses in the API that
can be exploited.


== Why is this an issue?

GraphQL introspection is a feature that allows client applications to query the
schema of a GraphQL API at runtime. It provides a way for developers to explore
and understand the available data and operations supported by the API.

This feature is a diagnostic tool that should only be used in the development
phase as its presence also creates risks.

Clear documentation and API references should be considered better
discoverability tools for a public GraphQL API.

=== What is the potential impact?

An attacker can use introspection to identify all of the operations and data
types supported by the server. This information can then be used to identify
potential targets for attacks.

==== Exploitation of private APIs

Even when a GraphQL API server is open to access by third-party applications, it
may contain APIs that are intended only for private use. Introspection allows
these private APIs to be discovered.

Private APIs often do not receive the same level of security rigor as public
APIs. For example, they may skip input validation because the API is only
expected to be called from trusted applications. This can create avenues for
attack that are not present on public APIs.

==== Exposure of sensitive data

GraphQL allows for multiple related objects to be retrieved using a single API
call. This provides an efficient method of obtaining data for use in a client
application.

An attacker may be able to use these relationships between objects to traverse
the data structure. They may be able to find a link to sensitive data that the
developer did not intentionally make available.


== How to fix it

=== Code examples

==== Noncompliant code example

[source,python,diff-id=1,diff-type=noncompliant]
----
from graphql_server.flask import GraphQLView

app.add_url_rule("/api",
    view_func=GraphQLView.as_view(  # Noncompliant
        name="api",
        schema=schema,
    )
)
----

==== Compliant solution

Make sure that introspection is disabled in production environments. You can use
the following code sample as a reference, in conjunction with your own methods
for distinguishing between production and non-production environments.

[source,python,diff-id=1,diff-type=compliant]
----
from graphql_server.flask import GraphQLView

# Only one of the following needs to be used
from graphql.validation import NoSchemaIntrospectionCustomRule # graphql-core v3
from graphene.validation import DisableIntrospection           # graphene v3


app.add_url_rule("/api",
    view_func=GraphQLView.as_view(
        name="api",
        schema=schema,
        validation_rules=[
            NoSchemaIntrospectionCustomRule,
            DisableIntrospection,
        ]
    )
)
----

=== How does this work?

==== Disabling introspection

The GraphQL server framework should be instructed to disable introspection in
production environments. This prevents any attacker attempt to retrieve schema
information from the server at runtime.

Each GraphQL framework will have a different method of doing this, possibly
including:

* Changing a simple boolean setting.
* Adding a middleware module to the request processing chain.
* Adding a GraphQL validator that rejects introspection keywords.

If introspection is required, it should only be made available to the smallest
possible audience. This could include development environments, users with a
specific right, or requests from a specific set of IP addresses.


== Resources

=== Articles & blog posts

* OWASP Web Security Testing Guide - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/12-API_Testing/01-Testing_GraphQL#introspection-queries[Testing GraphQL]

=== Standards

* OWASP - https://owasp.org/Top10/A05_2021-Security_Misconfiguration/[Top 10 2021 Category A5 - Security Misconfiguration]
* OWASP - https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[Top 10 2017 Category A3 - Sensitive Data Exposure]
* OWASP - https://owasp.org/www-project-top-ten/2017/A6_2017-Security_Misconfiguration[Top 10 2017 Category A6 - Security Misconfiguration]


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Disable GraphQL introspection on production environments.

=== Highlighting

Highlight the method or constructor call that is used to create the GraphQL
framework's request handler.

'''
endif::env-github,rspecator-view[]
