HIGH heap overflowaxumcockroachdb

Heap Overflow in Axum with Cockroachdb

Heap Overflow in Axum with Cockroachdb — how this specific combination creates or exposes the vulnerability

A heap overflow in an Axum service that uses CockroachDB can occur when unbounded or poorly validated request inputs are used to size buffers or construct data structures before being persisted. Axum, a Rust web framework, relies on safe abstractions, but unsafe code, unchecked lengths, or misuse of serialization buffers can introduce overflow risks that manifest in the process handling database interactions.

When a request carries a large payload—such as a bulk insert or a wide row definition—and is forwarded directly to CockroachDB without length checks, the application may allocate a buffer or Vec on the heap based on attacker-controlled values. If the size calculation exceeds what the runtime can safely support, the heap allocation may underflow or wrap, leading to corruption or unexpected behavior. This becomes more likely when deserializing complex JSON or protobuf payloads into structures that are later passed to CockroachDB via batch inserts or DDL operations.

The combination of Axum’s routing and extractor patterns with CockroachDB’s wire protocol or client libraries can expose subtle length and type mismatches. For example, extracting a JSON body into a loosely typed serde_value map and then constructing SQL rows from that map may result in oversized column values or unbounded arrays that are sent to CockroachDB. Although CockroachDB itself enforces server-side limits, the client-side allocations in Axum remain vulnerable to overflow if input validation is skipped.

Consider an endpoint that accepts a schema definition and corresponding rows to insert into a distributed table. If the number of columns or the size of each value is derived directly from user input without sanitization, the Axum handler may construct buffers or intermediate representations that exceed safe bounds. These overflows do not necessarily cause immediate crashes; they can corrupt adjacent memory, leading to data exposure or logic bypasses that affect how requests are forwarded to CockroachDB.

Because middleBrick scans the unauthenticated attack surface and tests inputs that reach the database layer, it can surface indicators of such unsafe handling. Findings related to input validation and unsafe consumption are particularly relevant when Axum services interact with CockroachDB, as they highlight areas where attacker-controlled data influences heap allocation before reaching the cluster.

Cockroachdb-Specific Remediation in Axum — concrete code fixes

Remediation focuses on strict input validation, bounded collections, and safe serialization before data reaches CockroachDB. In Axum, define extractors that enforce size limits and use strongly typed structures rather than loosely parsed JSON.

use axum::{routing::post, Router};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

#[derive(Deserialize, Serialize)]
struct SafeRow {
    id: i64,
    // enforce reasonable size at the type level
    #[serde(with = "bounded_bytes")]
    payload: Vec<u8>,
}

mod bounded_bytes {
    use serde::{self, Deserialize, Deserializer, Serializer};
    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let bytes = Vec::deserialize(deserializer)?;
        if bytes.len() > 65536 {
            return Err(serde::de::Error::custom("payload too large"));
        }
        Ok(bytes)
    }
    pub fn serialize<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_bytes(bytes)
    }
}

async fn create_rows(
    body: axum::extract::Json<SafeRow>,
) -> Result<impl axum::response::IntoResponse, (axum::http::StatusCode, String)> {
    // Construct a bounded batch insert for CockroachDB
    let client = cockroachdb::Client::new("postgresql://root@localhost:26257/mydb");
    let query = "INSERT INTO items (id, payload) VALUES ($1, $2)";
    client
        .query(query, &[&body.id, &body.payload])
        .await
        .map_err(|e| (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
    Ok(axum::http::StatusCode::CREATED)
}

pub fn app() -> Router {
    Router::new().route("/rows", post(create_rows))
}

This example uses a custom serde adapter to cap the payload size at 64 KiB, preventing unbounded heap growth before the data is sent to CockroachDB. The SQL statement uses parameterized queries to avoid injection while keeping the data representation bounded.

For bulk operations, validate the number of rows and total size before constructing the request:

use axum::extract::Json;

const MAX_ROWS: usize = 500;
const MAX_TOTAL_BYTES: usize = 10_000_000; // 10 MB

#[derive(Deserialize)]
struct BulkRequest {
    rows: Vec<RowData>,
}

#[derive(Deserialize)]
struct RowData {
    key: String,
    value: Vec<u8>,
}

async fn bulk_insert(
    Json(payload): Json<BulkRequest>,
) -> Result<impl axum::response::IntoResponse, (axum::http::StatusCode, String)> {
    if payload.rows.len() > MAX_ROWS {
        return Err((axum::http::StatusCode::BAD_REQUEST, "too many rows".into()));
    }
    let total_bytes: usize = payload.rows.iter().map(|r| r.value.len()).sum();
    if total_bytes > MAX_TOTAL_BYTES {
        return Err((axum::http::StatusCode::BAD_REQUEST, "total payload too large".into()));
    }
    // safe to forward to CockroachDB
    let client = cockroachdb::Client::new("postgresql://root@localhost:26257/mydb");
    for row in payload.rows {
        client
            .execute("INSERT INTO data (key, value) VALUES ($1, $2)", &[&row.key, &row.value])
            .await
            .map_err(|e| (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
    }
    Ok(axum::http::StatusCode::ACCEPTED)
}

By enforcing limits at the Axum layer, you ensure that only safely bounded data reaches CockroachDB, mitigating heap overflow risks that could otherwise be exploited through malformed requests.

Frequently Asked Questions

Why does Axum need explicit size limits when CockroachDB enforces its own limits?
CockroachDB enforces server-side limits, but client-side allocations in Axum can still overflow if unbounded inputs are used to construct buffers or batches. Applying limits at the Axum layer prevents heap corruption before data reaches the database.
Can middleBrick detect heap overflow risks in Axum services using CockroachDB?
Yes. middleBrick runs unauthenticated checks focused on input validation and unsafe consumption. Findings related to these checks highlight cases where attacker-controlled data could influence heap allocations prior to CockroachDB interaction.