HIGH nosql injectionaxummutual tls

Nosql Injection in Axum with Mutual Tls

Nosql Injection in Axum with Mutual Tls

Axum is a Rust web framework that does not include built-in query builders for NoSQL databases; developers typically integrate MongoDB, DynamoDB, or other stores via drivers. When an Axum service communicates with a NoSQL backend over a connection protected by mutual TLS (mTLS), the encryption and client authentication provided by mTLS address transport-layer threats, but they do not sanitize application-level input. If user-controlled data is deserialized and used to construct NoSQL queries, injection can still occur at the application layer. For example, a handler that directly embeds JSON fields into a MongoDB filter can allow an attacker to manipulate query logic even though the channel is authenticated and encrypted.

Consider an endpoint that retrieves user profiles by a string identifier without validation:

async fn get_user_profile(
    Extension(client): Extension,
    Json(payload): Json,
) -> Result, (StatusCode, String)> {
    let db = client.database("app");
    let collection = db.collection("users");
    let filter = doc! { "username": payload.username };
    let opt = collection.find_one(filter, None).await.map_err(|e| ...)?;
    ...
}

An attacker controlling payload.username can supply a value such as {"$ne": ""} or a JSON operator to change the semantics of the query. Although mTLS ensures the client is known, the database operation executes with the permissions of the service account, so unauthorized data exposure or logic bypass is possible. mTLS does not prevent this because it operates below the application layer; it authenticates peers but does not validate or escape data used by business logic.

Additionally, mTLS configurations can inadvertently encourage a false sense of security. Teams may assume encrypted channels eliminate injection concerns, leading to relaxed input validation. In Axum, route extractors deserialize payloads, but if developers skip validation libraries or custom checks, malformed or malicious constructs can propagate to database drivers. For instance, numeric fields may be coerced into strings and used in DynamoDB expression attribute paths, enabling injection through type confusion. The presence of mTLS changes the threat model for network attacks, but not for injection; the application must still treat all inputs as untrusted.

To detect such issues, scanning tools evaluate whether Axum handlers properly sanitize data before constructing queries, independent of transport protections. They check for usage of unchecked user input in database filters, validate deserialization patterns, and verify that mTLS is not relied upon to enforce data correctness. Remediation centers on strict validation, type-safe query construction, and avoiding direct concatenation of user data into NoSQL query structures.

Mutual Tls-Specific Remediation in Axum

Securing Axum services with mTLS requires both transport configuration and disciplined handling of data. For mTLS, the server must request and verify client certificates, and clients must present valid certs. Below are concrete examples using rustls with Axum, showing how to enforce mTLS and structure handlers to avoid injection.

1) Server-side mTLS setup with Axum:

use axum::{routing::get, Router};
use std::net::SocketAddr;
use tokio_rustls::rustls::{ServerConfig, NoClientAuth};
use tokio_rustls::TlsAcceptor;
use std::sync::Arc;

async fn run_server() -> Result<(), Box> {
    let mut server_config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth() // Start without client auth to configure later
        .with_single_cert(
            vec![include_bytes("server.crt")[..].to_vec()],
            include_bytes("server.key")[..].to_vec(),
        )?;

    // Enforce client certificate verification
    let client_roots = rustls::RootCertStore::empty();
    client_roots.add(&rustls::Certificate(include_bytes("ca.crt")[..].to_vec()))?;
    server_config.client_auth_root_subjects = client_roots.into();
    server_config.client_auth_mode = Some(rustls::server::ClientAuthMode::Required);

    let tls_acceptor = TlsAcceptor::from(Arc::new(server_config));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:8443").await?;
    let app = Router::new().route("/health", get(|| async { "ok" }));

    axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>(), tls_acceptor).await?;
    Ok(())
}

2) Handler with input validation and safe query building (MongoDB example):

use axum::{Extension, Json};
use mongodb::{bson::{doc, Document}, options::ClientOptions};
use serde::Deserialize;

#[derive(Deserialize)]
struct ProfileRequest {
    username: String,
}

async fn get_user_profile(
    Extension(client): Extension,
    Json(payload): Json,
) -> Result, (StatusCode, String)> {
    // Validate input: allow only alphanumeric usernames
    if !payload.username.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-') {
        return Err((StatusCode::BAD_REQUEST, "Invalid username format"[..].into()).into());
    }

    let db = client.database("app");
    let collection = db.collection("users");
    // Build query using a static key and validated value
    let filter = doc! { "username": payload.username };
    let opt = collection.find_one(filter, None).await.map_err(|e| ...)?;
    Ok(Json(opt.ok_or((StatusCode::NOT_FOUND, "Not found"[..].into()))?))
}

3) Ensuring mTLS is verified before business logic runs:

use axum::extract::connect_info::ConnectInfo;
use hyper::server::conn::AddrStream;

async fn handler_with_mtls_context(
    ConnectInfo(addr_info): ConnectInfo<AddrStream>,
) -> String {
    // At this point, the TLS layer has already verified the peer certificate
    format!("Connected via mTLS from {:?}", addr_info.remote_addr())
}

These patterns ensure that mTLS secures the channel while the application independently validates inputs, preventing NoSQL injection regardless of transport protections.

Frequently Asked Questions

Does mutual TLS prevent NoSQL injection in Axum services?
No. Mutual TLS authenticates peers and encrypts traffic, but it does not validate or sanitize application-level data. NoSQL injection is an application-layer issue and must be addressed through input validation, type-safe query construction, and avoiding direct embedding of user data into database queries.
What remediation steps are recommended for Axum services using NoSQL databases with mTLS?
Enforce mTLS for transport security and implement strict input validation (e.g., allowlist patterns, type checks) before using data in NoSQL queries. Use driver-native mechanisms for building queries safely, avoid string concatenation for filters, and validate all extractors and payloads independently of transport-layer protections.