Graphql Introspection Abuse in Aspnet
How GraphQL Introspection Abuse Manifests in ASP.NET
GraphQL introspection is a built-in feature that allows clients to query a GraphQL server for its schema, including all available types, fields, mutations, and directives. While essential for developer tools like GraphiQL and code generation, leaving introspection enabled on production APIs exposes the entire data structure to unauthenticated attackers. In ASP.NET applications using GraphQL libraries like GraphQL.NET or HotChocolate, introspection is often enabled by default, creating a security blind spot.
Attackers exploit this by sending a standard introspection query—a specially crafted GraphQL request that walks the schema and returns its complete definition. For ASP.NET GraphQL endpoints, this reveals not just field names but also internal comments, deprecated fields, and custom directives that may leak implementation details. For example, an attacker might discover hidden admin mutations or fields containing sensitive relationships that aren't apparent from the public API documentation.
Consider an ASP.NET Core application using GraphQL.NET with a schema that includes a User type having an internal ssn field used only by legacy services. If introspection is enabled, an attacker can discover this field and then craft a targeted query to extract social security numbers, even if the field isn't exposed in the primary API surface. This is especially dangerous in BOLA/IDOR scenarios where the attacker combines schema knowledge with object identifier tampering.
ASP.NET-specific code paths where this manifests include:
GraphQL.NET: TheSchemaclass andGraphQLSettingswhereEnableIntrospectiondefaults totrue.HotChocolate: TheGraphQLServerOptionsand schema configuration where introspection is enabled unless explicitly disabled viaDisableIntrospection.- Minimal API setups: When using
MapGraphQL()extension methods without configuration, introspection remains active.
graphql-cli or custom scripts, turning a 5-second scan into a complete API map.Detecting GraphQL Introspection in ASP.NET
Manual detection involves sending an introspection query to the GraphQL endpoint and analyzing the response. A successful introspection returns a JSON object with a __schema field containing the full type system. For ASP.NET GraphQL endpoints, a simple cURL test might look like:
curl -X POST https://api.example.com/graphql \
-H 'Content-Type: application/json' \
-d '{"query": "{ __schema { types { name fields { name } } } }"}'If the response includes a detailed schema (rather than an error like 'Introspection is disabled'), the endpoint is vulnerable. However, manual testing doesn't scale across multiple APIs or track changes over time.
This is where middleBrick automates detection. Its black-box scanner sends a battery of standardized introspection queries (including complex ones that traverse nested types and directives) to every discovered GraphQL endpoint. If the server returns any schema data, middleBrick flags it under its Inventory Management check—because exposing the entire API structure is an inventory leakage risk. The scan takes 5–15 seconds and requires no credentials, making it ideal for continuous monitoring of ASP.NET APIs in CI/CD pipelines via the GitHub Action or through the CLI tool (middlebrick scan https://api.example.com/graphql).
middleBrick's report will show:
- Whether introspection is enabled.
- Sample excerpts of the leaked schema (truncated for safety).
- Severity rating (typically High, as this facilitates further attacks).
- Remediation guidance specific to ASP.NET configuration.
Remediating GraphQL Introspection in ASP.NET
Remediation involves disabling introspection in production while potentially keeping it enabled in development environments. ASP.NET GraphQL libraries provide straightforward configuration options.
For GraphQL.NET (v4.x and above):
// Program.cs or Startup.cs
services.AddGraphQL(options =>
{
options.EnableIntrospection = false; // Disable globally
// Other settings...
})
.AddSystemTextJson()
.AddErrorInfoProvider<ErrorInfoProvider>()
.AddSchema<MySchema>()
.AddGraphTypes(typeof(MySchema).Assembly);Alternatively, you can conditionally disable based on environment:
var isProduction = app.Environment.IsProduction();
services.AddGraphQL(options =>
{
options.EnableIntrospection = !isProduction;
});For HotChocolate (v12.x and above):
// Program.cs
services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.ModifyOptions(o => o.EnableIntrospection = false); // Disable globallyHotChocolate also supports per-endpoint control via middleware:
app.MapGraphQL()
.RequireAuthorization(new AuthorizeAttribute { Roles = "Admin" });
// Even if introspection is enabled, only authorized users can access the schema.Additional Defense-in-Depth:
- Network-level restrictions: Place GraphQL endpoints behind a firewall or API gateway that only allows trusted IPs (e.g., internal developer networks).
- Rate limiting: Use ASP.NET Core's
RateLimitermiddleware or a solution likeAspNetCoreRateLimitto throttle introspection attempts, though this is a secondary control. - Schema design: Avoid including sensitive fields in the GraphQL schema altogether. Use separate schemas for internal vs. public APIs if feasible.
After applying fixes, re-scan with middleBrick to verify that introspection is no longer detectable. The Pro plan's continuous monitoring can schedule daily scans and alert via Slack/Teams if introspection accidentally re-appears after a deployment.