Graphql Introspection in Django

How Graphql Introspection Manifests in Django

Graphql Introspection is a powerful GraphQL feature that allows clients to query the schema of an API to discover available types, queries, mutations, and fields. While invaluable for development and documentation, this capability becomes a significant security risk when exposed in production environments. In Django applications, GraphQL introspection manifests through several specific attack patterns that can expose your entire API surface to malicious actors.

The most common manifestation occurs through the __schema query, which returns the complete schema definition. Attackers can use this to map out every available query, mutation, and subscription, including field types, arguments, and even documentation strings. In Django applications using libraries like Graphene-Django or Strawberry, this endpoint is often enabled by default and accessible without authentication.

A particularly dangerous attack pattern involves combining introspection with automated tooling. Once an attacker obtains the schema, they can feed it into tools like graphql-fuzz or graphql-pathfinder to systematically discover vulnerable queries, injection points, and data exposure vulnerabilities. The introspection response typically includes detailed type information, field descriptions, and even example queries, providing attackers with a comprehensive roadmap for exploitation.

In Django applications, introspection often reveals sensitive implementation details. For instance, it might expose internal field names that differ from public-facing names, reveal database table structures through type names, or expose administrative mutations that should only be available to privileged users. This information leakage can be particularly damaging when combined with other vulnerabilities like BOLA (Broken Object Level Authorization) or IDOR (Insecure Direct Object References).

The risk is amplified in Django applications that use complex model relationships or custom resolvers. Introspection can reveal nested relationships, permission structures, and even business logic that should remain hidden from external consumers. Attackers can use this information to craft sophisticated queries that bypass intended access controls or extract sensitive data through GraphQL's powerful filtering and relationship traversal capabilities.

Another manifestation involves the introspection HTTP header, which some GraphQL servers use to control introspection behavior. Attackers can manipulate this header to bypass disabled introspection endpoints or to trigger different behaviors in vulnerable implementations. Django applications that don't properly validate or sanitize this header become susceptible to header-based attacks that can expose schema information even when introspection is supposedly disabled.

Django-Specific Detection

Detecting GraphQL introspection vulnerabilities in Django applications requires a multi-faceted approach that combines manual testing with automated scanning. The first step is to identify whether your Django application exposes a GraphQL endpoint and whether introspection is enabled. This can be done by sending a simple introspection query to your GraphQL endpoint:

 

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH