Information Disclosure in Axum with Cockroachdb
Information Disclosure in Axum with Cockroachdb — how this specific combination creates or exposes the vulnerability
Information Disclosure occurs when an application unintentionally exposes data to parties that should not have access. In the context of an Axum web service using Cockroachdb as the backend database, the risk arises from a mismatch between API surface, database permissions, and error handling practices. Axum, a Rust web framework, handles requests asynchronously and can stream data directly from database connections. If route handlers construct SQL dynamically or rely on ORM behaviors that expose internal identifiers, they may leak records through endpoints that should enforce tenant or ownership boundaries.
With Cockroachdb, a distributed SQL database, Information Disclosure can manifest through several vectors specific to the combination. First, connection strings or session settings may inadvertently expose cluster topology or node identifiers in logs or error traces. Second, Cockroachdb’s multi-tenancy features—such as secondary tenants—can interact with Axum’s routing logic to allow cross-tenant queries if row-level security is not enforced at the application layer. Third, detailed error messages returned by Cockroachdb (e.g., constraint violations or serialization failures) may include table names, column names, or key data that an attacker can use to refine enumeration attacks.
A concrete scenario: an Axum handler retrieves a document by ID using a path parameter doc_id. If the handler builds a query like format!("SELECT content FROM documents WHERE id = {doc_id}"), it opens the door to SQL injection and data scraping. Even if parameterized queries are used, missing ownership checks can allow an authenticated user to request /documents/123 while their tenant only owns documents in shard A, and Cockroachdb may return data from shard B due to replication or misconfigured secondary indexes. The framework will return the record with a 200 status, disclosing information that should have been filtered out. Additionally, Cockroachdb’s SHOW and EXPLAIN commands, if reachable through debug endpoints, can disclose schema details that broaden the attack surface.
Middleware and logging configurations in Axum can exacerbate the issue. If response errors are serialized with full tracebacks, Cockroachdb error codes (such as pq::error::SqlState values) may be exposed to clients. These codes can hint at the underlying storage layer structure. Rate limiting and authentication checks must be applied uniformly; otherwise, unauthenticated probing of endpoints may return different data exposure patterns, which middleBrick’s LLM/AI Security checks would flag as system prompt leakage or output anomalies when testing API behavior.
To mitigate Information Disclosure in this stack, developers must treat the API boundary as a security perimeter. Validate and sanitize all inputs before constructing queries, enforce tenant context at the handler level, and ensure Cockroachdb permissions follow the principle of least privilege. Use structured logging that redacts sensitive fields, and avoid exposing raw database errors to HTTP responses. Continuous scanning with tools that understand API behavior—such as middleBrick’s 12 security checks—can detect missing authorization, improper error handling, and data exposure risks before they reach production.
Cockroachdb-Specific Remediation in Axum — concrete code fixes
Remediation focuses on strict input validation, parameterized queries, and explicit tenant scoping. In Axum, extract path and query parameters into typed structures and validate them before use. Always use Cockroachdb prepared statements or an ORM that supports parameterized queries to prevent injection and accidental data leakage. Below are concrete examples tailored to an Axum handler using tokio-postgres with Cockroachdb.
1. Parameterized Query with Tenant Context
Ensure every query includes a tenant filter and uses placeholders. This prevents cross-tenant reads even if row-level security is misconfigured.
use axum::{routing::get, Router, extract::State};
use tokio_postgres::{NoTls, Client};
use serde::Deserialize;
#[derive(Deserialize)]
struct DocumentParams {
doc_id: i64,
}
struct AppState {
db_client: Client,
tenant_id: String,
}
async fn get_document_handler(
State(state): State<AppState>,
params: axum::extract::Query<DocumentParams>,
) -> Result<axum::Json<serde_json::Value>, (axum::http::StatusCode, String)> {
let query = "SELECT content, owner_tenant FROM documents WHERE id = $1 AND tenant_id = $2";
let row = state.db_client
.query_opt(query, &[¶ms.doc_id, &state.tenant_id])
.await
.map_err(|e| (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
match row {
Some(r) => {
let content: String = r.get(0);
Ok(axum::Json(serde_json::json!({ "content": content })))
}
None => Err((axum::http::StatusCode::NOT_FOUND, "Document not found".into())),
}
}
2. Enforce Tenant Scoping with Middleware
Add an Axum layer that injects tenant context into request extensions, ensuring every downstream handler applies the filter.
use axum::{async_trait, extract::FromRequest, http::Request};
use std::future::Future;
use std::pin::Pin;
struct TenantId(String);
#[async_trait]
impl<S: Send + Sync> FromRequest<S> for TenantId {
type Rejection = (axum::http::StatusCode, String);
type Fut = Pin<Box
3. Safe Error Handling to Avoid Data Exposure
Map Cockroachdb errors to generic HTTP responses. Do not forward raw error strings or SQL state codes to the client.
async fn safe_db_query(client: &Client, query: &str, params: &[&(dyn tokio_postgres::types::ToSql + Sync)]) -> Result<Vec<tokio_postgres::Row>, (axum::http::StatusCode, String)> {
client.query(query, params)
.await
.map_err(|e| {
// Log detailed error internally, return generic message
eprintln!("Database error: {}", e);
(axum::http::StatusCode::INTERNAL_SERVER_ERROR, "Request failed".into())
})
}
4. Connection and Session Hardening
Configure Cockroachdb connection strings to disable unwanted features and set appropriate application name for tracing without exposing internals.
let config = "postgresql://user:password@host:26257/dbname?sslmode=require&application_name=axum-service&options=--cluster-settings-escape-pct%3Doff";
let (client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap();
Ensure the options parameter does not expose sensitive runtime details. Use Cockroachdb’s SHOW CLUSTER SETTING only from administrative tooling, not from request-handling paths.