HIGH graphql introspectionaxumcockroachdb

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 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

Frequently Asked Questions

How does middleBrick detect GraphQL introspection exposure?
MiddleBrick runs unauthenticated checks that query the GraphQL endpoint with an introspection request. If the response includes schema types, fields, or relationships that map to CockroachDB-backed resources, it flags the finding under Property Authorization and Data Exposure, providing severity and remediation steps.
Can the GraphQL endpoint be scanned if it requires authentication?
MiddleBrick scans the unauthenticated attack surface. If authentication is required, findings may be limited. You can provide a test token or session via the dashboard or CLI to enable deeper authenticated scans when supported.