Graphql Introspection in Aspnet with Cockroachdb
Graphql Introspection in Aspnet with Cockroachdb — how this specific combination creates or exposes the vulnerability
GraphQL introspection in an ASP.NET application that uses CockroachDB can expose metadata about your schema, queries, and underlying data structure. When introspection is enabled in production, an attacker can discover types, queries, and mutations, which may reveal sensitive business logic or data models. If your ASP.NET GraphQL server is connected to CockroachDB, introspection responses can indirectly expose database-related patterns such as table-like entity names, field types, and relationships inferred from the GraphQL schema.
In this stack, the risk is amplified when the GraphQL endpoint is unauthenticated or weakly authenticated, as part of the unauthenticated attack surface tested by middleBrick. An attacker can use standard GraphQL introspection queries to map the API surface and identify endpoints that interact with CockroachDB-backed data stores. This can aid in crafting further attacks such as injection or excessive data extraction. Because CockroachDB often serves as a distributed SQL backend, schema elements like table names or column types may be reflected in the GraphQL type definitions, giving an attacker a clearer picture of the persistence layer.
For example, if your ASP.NET GraphQL server defines a Product type with fields that map to CockroachDB table columns, introspection reveals those fields and their types. Combined with other unchecked inputs, this information can be used to refine injection or IDOR testing. middleBrick scans this attack surface by running 12 checks in parallel, including Input Validation, Property Authorization, and SSRF, to highlight risky exposure of introspection and related endpoints without requiring credentials.
Cockroachdb-Specific Remediation in Aspnet — concrete code fixes
To reduce exposure, disable or restrict GraphQL introspection in production for ASP.NET applications backed by CockroachDB. You can configure the GraphQL settings to disable introspection or allow it only for trusted clients. Below are concrete examples using Hot Chocolate, a popular GraphQL server for ASP.NET.
Disable introspection in schema setup
using HotChocolate;
using HotChocolate.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Configure GraphQL server with introspection disabled
builder.Services
.AddGraphQLServer()
.AddQueryType()
.ModifyOptions(options => options.EnableIntrospection = false);
var app = builder.Build();
app.MapGraphQL();
app.Run();
public class Query
{
public string GetProduct(int id) => "Product from CockroachDB";
}
Allow introspection only for authenticated users
using HotChocolate;
using HotChocolate.AspNetCore;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGraphQLServer()
.AddQueryType();
// Require authentication to enable introspection
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapGraphQL(new GraphQLServerOptions
{
EnableIntrospection = true,
AuthorizationResolver = context =>
{
var auth = context.HttpContext.User.Identity?.IsAuthenticated ?? false;
// Only allow introspection for authenticated users
return auth ? AuthorizeResult.Authorized : AuthorizeResult.NotAuthorized;
}
});
app.Run();
public class Query
{
public string GetOrder(int id) => "Order from CockroachDB";
}
Use schema filters to limit exposed types and fields
using HotChocolate;
using HotChocolate.AspNetCore;
using HotChocolate.Types.Descriptors;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGraphQLServer()
.AddQueryType()
.AddType()
.AddTypeFilter();
var app = builder.Build();
app.MapGraphQL();
app.Run();
public class Query
{
public Product GetProduct(int id) => new() { Id = id, Name = "Widget" };
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
internal string Secret { get; set; } = "hidden";
}
public class ProductType : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor.Field(p => p.Id).Type();
descriptor.Field(p => p.Name).Type();
// Internal fields are not exposed by default if filter is applied
}
}
public class ExcludeInternalTypesFilter : ITypeFilter
{
public void OnConfigure(ITypeDescriptor descriptor, Type type, FilterLevel level)
{
if (type == typeof(Product) && descriptor is IObjectDescriptor objectDescriptor)
{
// Remove internal fields from introspection
var internalFields = objectDescriptor.Fields.Where(f => f.Property?.GetMethod?.IsPrivate == true ||
f.Property?.GetMethod?.IsAssembly == true);
foreach (var field in internalFields)
{
objectDescriptor.RemoveField(field.Name);
}
}
}
}
Additionally, ensure your CockroachDB connection string and queries avoid exposing schema details through error messages. Use parameterized queries to prevent injection and avoid returning raw database identifiers in GraphQL responses. These steps reduce the risk of exposing CockroachDB-specific patterns through GraphQL introspection.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |