HIGH pii leakageaxummongodb

Pii Leakage in Axum with Mongodb

Pii Leakage in Axum with Mongodb — how this specific combination creates or exposes the vulnerability

When building web services with the Axum web framework in Rust, integrating with MongoDB as the data store introduces specific risks around personally identifiable information (PII) leakage if data access and serialization are not carefully controlled. Axum provides a flexible handler model where request data, including path parameters, query strings, and JSON payloads, is deserialized into Rust structures. If these structures or the subsequent MongoDB queries expose fields such as email, phone, national ID, or exact location, and responses are not explicitly filtered, PII can be returned to clients unintentionally.

MongoDB documents often store nested objects and arrays that may contain sensitive fields. In Axum, handlers commonly deserialize incoming JSON into strongly typed structs using Serde, then construct a MongoDB filter or update document—frequently via the official MongoDB Rust driver—based on that data. If the handler returns the full MongoDB document or a partially filtered struct, any PII present in the stored document can be exposed. For example, a user profile endpoint that retrieves a document and returns it as JSON may leak fields like email, ssn, or address unless those fields are explicitly omitted during serialization.

The risk increases when route parameters or query inputs are used directly to construct MongoDB queries without proper validation or projection. Consider a search endpoint that accepts a query parameter and returns matching user documents. If the handler does not specify a projection to exclude sensitive fields, the response can contain PII from each matched document. Additionally, logging or error messages that include MongoDB document contents can further expose PII in application logs or stack traces. MiddleBrick’s LLM/AI Security checks highlight system prompt leakage and output scanning for PII, which can detect when API responses inadvertently include sensitive information such as email patterns or key-like strings in responses from AI-assisted integrations.

Another vector involves the use of MongoDB’s aggregation pipeline within Axum handlers. If stages such as $project or $addFields are omitted or incorrectly configured, sensitive fields may remain in the pipeline output. Axum’s extractor patterns can also inadvertently pass sensitive data between layers if request guards or extractors are not scoped to the necessary subset of fields. Because MongoDB’s flexible schema allows diverse documents within a collection, a single endpoint can return varying sets of fields, some containing PII, depending on how documents were inserted. Without consistent schema governance and explicit response filtering, the combination of Axum’s dynamic routing and MongoDB’s document model creates a pathway for PII leakage that may not be apparent during development.

Mongodb-Specific Remediation in Axum — concrete code fixes

To mitigate PII leakage in an Axum application using MongoDB, apply explicit projection and serialization controls at the handler and data access layers. Always define distinct request, domain, and response structs so that only necessary fields are exposed through JSON serialization. Use Serde attributes to skip or rename sensitive fields, and construct MongoDB queries with explicit projections to exclude sensitive data from the query results.

Below are concrete, working Rust examples for an Axum handler that retrieves a user profile without exposing PII. The example uses the official MongoDB Rust driver and Serde to control serialization.

// Cargo.toml dependencies:
// axum = "0.6"
// mongodb = "2.8"
// serde = { version = "1.0", features = ["derive"] }
// tokio = { version = "1", features = ["full"] }

use axum::{routing::get, Router};
use mongodb::{bson::doc, options::FindOptions, Client};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

// Request DTO: only what the endpoint accepts
#[derive(Deserialize)]
struct GetUserRequest {
    user_id: String,
}

// Domain/model: represents full document in MongoDB
#[derive(Debug, Deserialize)]
struct UserDocument {
    #[serde(rename = "_id")]
    id: String,
    email: String,
    phone: String,
    ssn: String,
    address: String,
    // other fields...
}

// Response DTO: explicitly excludes PII
#[derive(Serialize)]
struct UserResponse {
    id: String,
    // Do not include email, phone, ssn, address
}

async fn get_user(
    GetUserRequest { user_id }: GetUserRequest,
    client: axum::extract::State,
) -> Result, (axum::http::StatusCode, String)> {
    let db = client.database("app_db");
    let collection = db.collection::("users");

    // Use projection to exclude PII at the database level
    let filter = doc! { "_id": &user_id };
    let options = FindOptions::builder().projection(doc! { "email": 0, "phone": 0, "ssn": 0, "address": 0 }).build();

    let result = collection.find_one(filter, options).await
        .map_err(|e| (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;

    match result {
        Some(doc) => Ok(axum::Json(UserResponse { id: doc.id })),
        None => Err((axum::http::StatusCode::NOT_FOUND, "User not found".to_string())),
    }
}

#[tokio::main]
async fn main() {
    let client = Client::with_uri_str("mongodb://localhost:27017").expect("valid uri");
    let app = Router::new().route("/users/:user_id", get(get_user))
        .with_state(client);

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

In this example, the MongoDB driver applies the projection to exclude email, phone, ssn, and address from the returned document, ensuring that even if the stored document contains these fields, they are not sent to the client. The response struct UserResponse further enforces minimal exposure by including only the id field. For endpoints that support filtering or listing, always use projections and avoid returning full documents. Additionally, sanitize any error messages and avoid logging raw MongoDB documents to prevent PII leakage in observability data. MiddleBrick’s dashboard and CLI can scan these handlers and flag endpoints that return broad or unfiltered responses, helping teams iteratively reduce exposure.

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 can I verify that my Axum endpoints are not leaking PII to MongoDB responses?
Use explicit projections in your MongoDB queries to exclude sensitive fields and define separate response structs without PII. Run scans with a tool that inspects API output for patterns like email or API keys; the MiddleBrick CLI can be integrated into scripts to automate checks and report potential leakage points.
Does using MongoDB field-level encryption prevent PII leakage in Axum APIs?
Field-level encryption protects data at rest and in transit within MongoDB, but it does not prevent an authorized application from returning PII in API responses. You must still control what data your Axum handlers return by using projections and response DTOs to limit exposed fields.