HIGH nosql injectionaxumbasic auth

Nosql Injection in Axum with Basic Auth

Nosql Injection in Axum with Basic Auth — how this specific combination creates or exposes the vulnerability

In Axum, a Rust web framework, Nosql Injection occurs when user-controlled input is directly interpolated into a NoSQL query or builder without validation or parameterization. Axum does not provide built-in query sanitization for database drivers; it relies on developers to construct safe queries. When Basic Auth is used, the username and password are typically parsed from the Authorization header and often passed into downstream logic such as database lookups for user authentication or role retrieval.

If the username or password derived from Basic Auth is used to build a NoSQL query—such as a MongoDB filter or a DynamoDB condition—and concatenated as strings, an attacker can inject crafted payloads like {'$ne': null} or {'$where': 'true'} to bypass authentication or extract data. For example, a developer might write a filter using the username directly: doc!{"username": username, "password": password}. If username is admin and password is "$ne: " + "null", the resulting document may unintentionally change semantics, leading to authentication bypass or unauthorized data access.

Since Basic Auth transmits credentials in a base64-encoded header (not encrypted), interception risks compound the impact if the transport is not protected by TLS. MiddleBrick scans detect unauthenticated endpoints and can identify whether endpoints that accept Basic Auth are vulnerable to injection-like patterns by correlating spec definitions with runtime behavior. The scanner checks whether authentication handlers properly validate and parameterize inputs before constructing queries, flagging cases where user-controlled data reaches database-building code without sanitization.

In practice, this vulnerability maps to the OWASP API Top 10 category 'Broken Object Level Authorization' and can lead to unauthorized access or data leakage. Axum applications that parse headers manually and forward credentials to NoSQL backends must ensure strict type handling, avoid string-based query assembly, and use prepared patterns or typed structs that the database driver can safely encode.

Basic Auth-Specific Remediation in Axum — concrete code fixes

Remediation centers on never using raw header values directly in database queries. Instead, treat credentials as opaque identifiers and validate them against a parameterized data store. Use strong types and avoid string concatenation when building NoSQL filters.

Example of vulnerable code in Axum that combines Basic Auth with a MongoDB-like filter construction:

// Vulnerable: direct string usage in a filter
async fn login_handler(
    Extension(pool): Extension>,
    headers: HeaderMap,
) -> Result {
    let auth = headers.get("authorization")
        .ok_or((StatusCode::UNAUTHORIZED, "Missing auth".to_string()))?
        .to_str().map_err(|_| (StatusCode::BAD_REQUEST, "Bad encoding".to_string()))?;
    let creds = decode_basic(auth); // returns (username, password)
    let username = creds.0;
    let password = creds.1;

    // Unsafe: building a filter by interpolating strings
    let filter = doc! { "username": username, "password": password };
    let user = collection.find_one(filter, None).await.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
    // ...
}

Correct approach using typed structures and parameterized checks:

// Safe: use typed structs and let the driver handle values
#[derive(Deserialize)]
struct Credentials {
    username: String,
    password: String,
}

async fn safe_login_handler(
    Extension(pool): Extension>,
    headers: HeaderMap,
) -> Result {
    let auth = headers.get("authorization")
        .ok_or((StatusCode::UNAUTHORIZED, "Missing authorization".into()))?
        .to_str().map_err(|_| (StatusCode::BAD_REQUEST, "Invalid header".into()))?;
    let creds = decode_basic(auth).map_err(|_| (StatusCode::UNAUTHORIZED, "Invalid credentials".into()))?;

    // Use a parameterized query via a typed struct or prepared statement
    let user: Option = collection
        .find_one(doc! { "username": &creds.username, "password_hash": hash_password(&creds.password) }, None)
        .await
        .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;

    match user {
        Some(u) => Ok(Json(u)),
        None => Err((StatusCode::UNAUTHORIZED, "Invalid credentials".into())),
    }
}

Additional measures include enforcing TLS, using hashed passwords, and validating input length and characters before using them in any backend call. MiddleBrick can verify that such patterns are in place by scanning the unauthenticated surface and noting whether endpoints leak credentials in error messages or accept injection-prone payloads.

Frequently Asked Questions

Can Basic Auth headers be safely used with NoSQL queries if they are base64 encoded?
No. Base64 encoding is not encryption; it provides no integrity or confidentiality. Credentials in headers should be validated and never directly interpolated into query structures. Always use parameterized queries and strong transport security.
How does middleBrick detect NoSQL injection risks in endpoints using Basic Auth?
MiddleBrick runs unauthenticated checks that analyze OpenAPI/Swagger specs and runtime behavior to see if user-controlled data from authentication headers reaches database-building logic. It flags missing parameterization and highlights findings mapped to OWASP API Top 10 with remediation guidance.