Graphql Introspection in Axum with Cockroachdb
Graphql Introspection in Axum with Cockroachdb — how this specific combination creates or exposes the vulnerability
GraphQL introspection exposes the schema of an API, including types, queries, and mutations. When used unintentionally in an Axum service backed by CockroachDB, it can reveal implementation details that aid attackers. In Axum, if a GraphQL endpoint is publicly reachable and introspection is enabled, an attacker can query the schema to discover available queries, mutations, and the shape of data models that map to CockroachDB tables.
This combination becomes risky because CockroachDB often stores sensitive or regulated data (e.g., personal or financial records). If introspection is allowed in production, an attacker can enumerate fields such as users, api_keys, or internal_flags, inferring data relationships and targeting injection or privilege escalation paths. MiddleBrick scans detect this as part of the Property Authorization and Data Exposure checks, highlighting whether introspection responses include sensitive types or relationships that should be restricted.
Additionally, introspection responses may expose database-backed types that include primary keys or foreign keys, which can be chained to Insecure Direct Object Reference (IDOR) or Broken Object Level Authorization (BOLA) issues. For example, a user_id field exposed in a GraphQL type can be manipulated if authorization checks are missing. The scanner correlates runtime findings with OpenAPI/Swagger specs (including $ref resolution) and flags discrepancies, ensuring that GraphQL introspection does not leak schema details that map to CockroachDB-backed resources.
Unauthenticated introspection is particularly dangerous when combined with public endpoints. MiddleBrick’s LLM/AI Security checks also assess whether introspection is accessible without authentication, as part of its unauthenticated endpoint detection. Without proper safeguards, attackers can use introspection to plan further attacks, such as crafting malicious queries or probing for rate-limiting behaviors.
To mitigate this within the Axum and CockroachDB stack, restrict introspection to trusted environments, validate the origin of requests, and ensure that authorization logic is applied consistently across GraphQL resolvers that interact with CockroachDB. MiddleBrick’s findings include prioritized remediation guidance, helping teams disable or protect introspection in production while maintaining development utility.
Cockroachdb-Specific Remediation in Axum — concrete code fixes
Securing GraphQL introspection in Axum when using CockroachDB requires a combination of schema design, runtime checks, and environment controls. Below are concrete, working examples that demonstrate how to implement remediation.
1. Disable introspection in production via environment configuration
Ensure introspection is only enabled in development or explicitly allowed environments. Use Axum extractors to conditionally enable introspection based on configuration.
use axum::routing::post;
use axum::Router;
use std::net::SocketAddr;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let introspection_enabled = std::env::var("ENABLE_INTROSPECTION")
.map(|v| v == "true")
.unwrap_or(false);
let app = Router::new()
.route("/graphql", post(graphql_handler))
.with_state(AppState { introspection_enabled });
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
struct AppState {
introspection_enabled: bool,
}
async fn graphql_handler(
State(state): State,
Extension(client): Extension,
RequestBody(payload)): RequestBody,
) -> Result, (StatusCode, String)> {
if payload.is_introspection && !state.introspection_enabled {
return Err((StatusCode::FORBIDDEN, "introspection disabled".to_string()));
}
// proceed with query execution against CockroachDB
Ok(Json(execute_graphql(&client, payload).await?))
}
2. Apply role-based authorization in resolvers that access CockroachDB
Ensure that each resolver validates user permissions before executing SQL. Use a session or JWT claim to determine access rights.
async fn execute_query(
client: &cockroachdb::Client,
query: &str,
user_role: &str,
) -> Result, sqlx::Error> {
match user_role {
"admin" => {
let rows = client.query(query, &[]).await?;
Ok(rows_to_json(rows))
}
"user" => {
// restrict to user-specific data
let limited_query = format!("{query} WHERE user_id = current_user_id()");
let rows = client.query(&limited_query, &[]).await?;
Ok(rows_to_json(rows))
}
_ => Err(sqlx::Error::Configuration(
"unauthorized role".into(),
)),
}
}
3. Use CockroachDB’s prepared statements and parameterized queries
This prevents injection and ensures that schema introspection does not lead to unsafe SQL execution.
async fn get_user_by_id(client: &cockroachdb::Client, user_id: i32) -> Result {
let row = client
.query_one("SELECT id, name, email FROM users WHERE id = $1", &[&user_id])
.await?;
Ok(User {
id: row.get(0),
name: row.get(1),
email: row.get(2),
})
}
4. Restrict introspection via network and middleware controls
Use Axum middleware to block introspection queries from untrusted IP ranges in production. Combine this with CockroachDB’s network policies to limit exposure.
async fn introspection_middleware(req: Request<B>, extensions: &Extensions) -> Result {
let state = extensions.get::<AppState>().ok_or((StatusCode::INTERNAL_SERVER_ERROR, "missing state"))?;
if req.uri().path() == "/graphql" && req.method() == Method::POST {
let body = req.into_body();
// parse payload to detect introspection query
if is_introspection_query(&body) && !state.introspection_enabled {
return Err((StatusCode::FORBIDDEN, "introspection disabled".to_string()));
}
}
Ok(req)
}
By combining these techniques, teams can safely use GraphQL introspection during development while minimizing exposure in production. MiddleBrick’s scans validate that such controls are in place and flag any remaining exposure paths that involve CockroachDB-backed GraphQL schemas.
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 |