HIGH ldap injectionaxumcockroachdb

Ldap Injection in Axum with Cockroachdb

Ldap Injection in Axum with Cockroachdb — how this specific combination creates or exposes the vulnerability

LDAP injection occurs when untrusted input is concatenated into LDAP queries without validation or escaping, allowing an attacker to manipulate the query structure. In an Axum application that uses CockroachDB as a backend data store, this typically happens when user-supplied values such as a username or search filter are embedded into an LDAP filter string and then used to query an LDAP server.

Consider an Axum handler that builds an LDAP filter from a login identifier stored in a CockroachDB row. If the identifier is taken directly from request input and concatenated into the filter, characters like parentheses, asterisks, or logical operators can change the query semantics. For example, a username like admin)(objectClass=*) could turn a simple equality check into a wildcard match that bypasses authentication. Even when CockroachDB holds only application metadata (e.g., mapping a user to their LDAP DN), an attacker who can control the input may affect which DN is sent to the LDAP backend, enabling authentication as a different user or extraction of directory information through crafted filters.

The risk is contextual: Axum does not provide LDAP-specific helpers, so developers build filters manually. CockroachDB may store the base distinguished name (DN) or mapping keys, but it does not sanitize LDAP filter syntax. If the application trusts data from the database or from HTTP request parameters and concatenates them into an LDAP filter, the unauthenticated attack surface includes both the API endpoint and the directory service. This combination exposes the application to classic LDAP injection techniques such as filter chaining, attribute extraction, and bypassing authentication logic.

In a black-box scan, an API endpoint that reflects LDAP error messages or timing differences can reveal whether injection succeeded. Because middleBrick tests input validation and authentication without credentials, it can surface LDAP injection findings when concatenated inputs affect authentication or directory queries. Remediation focuses on strict input validation, using parameterized approaches where possible, and ensuring that data from CockroachDB is treated as untrusted when building LDAP filters.

Cockroachdb-Specific Remediation in Axum — concrete code fixes

Secure Axum handlers should avoid string concatenation for LDAP filters. Instead, treat any identifier from CockroachDB or HTTP input as untrusted and escape or validate it according to LDAP filter rules. Below are concrete patterns you can adopt.

1. Parameterized queries for data retrieval

When reading user mappings from CockroachDB, use parameterized SQL to avoid injection at the database layer and keep data clean for downstream use.

// src/main.rs
use sqlx::postgres::PgQueryAs;
use axum::extract::Query;
use serde::Deserialize;

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

// Fetch a mapping safely; CockroachDB driver enforces parameterization
pub async fn get_user_mapping(
    pool: &sqlx::PgPool,
    username: &str,
) -> Result, sqlx::Error> {
    sqlx::query_as!(UserMapping,
        "SELECT id, ldap_dn FROM user_mappings WHERE username = $1",
        username
    )
    .fetch_optional(pool)
    .await
}

#[derive(sqlx::FromRow)]
struct UserMapping {
    id: i32,
    ldap_dn: String,
}

2. Escaping LDAP filter components

When constructing an LDAP filter, escape special characters defined in RFC 4515: *, (, ), \, and the null byte. Implement a small sanitizer and use it before concatenation.

// src/ldap.rs
pub fn escape_filter(value: &str) -> String {
    let mut out = String::with_capacity(value.len() * 2);
    for ch in value.chars() {
        match ch {
            '*' | '(' | ')' | '\\' => {
                out.push('\\');
                out.push(ch);
            }
            '\x00' => out.push_str("\\00"),
            _ => out.push(ch),
        }
    }
    out
}

// Usage in an Axum handler
use axum::extract::State;
use ldap3::{LdapConnAsync, Scope, SearchEntry};

pub async fn handle_login(
    State(pool): State>,
    username: String,
) -> Result {
    let mapping = get_user_mapping(&pool, &username).await.map_err(|e| e.to_string())?;
    let mapping = mapping.ok_or("user not found")?;

    let safe_username = escape_filter(&username);
    let filter = format!("(&(objectClass=person)(uid={}))", safe_username);

    let (mut ldap, mut ldap_conn) = LdapConnAsync::new("ldap://localhost:389").await.map_err(|e| e.to_string())?;
    let result = ldap.search(
        &mapping.ldap_dn,
        Scope::Subtree,
        &filter,
        vec!["cn", "mail"],
    ).await.map_err(|e| e.to_string())?;

    // Process entries...
    Ok("success".to_string())
}

3. Defense in depth

Validate username format before querying CockroachDB (e.g., allow only alphanumerics and a limited set of symbols), and avoid returning raw LDAP errors to the client. Use structured logging for diagnostics without exposing filter strings. These steps reduce the likelihood that data from CockroachDB or HTTP input can alter LDAP semantics.

Frequently Asked Questions

Does middleBrick detect LDAP injection in Axum applications?
Yes. middleBrick tests authentication and input validation in parallel. When untrusted input affects LDAP filter construction, findings related to input validation and authentication are reported with severity, impact, and remediation guidance.
Can CockroachDB store malicious LDAP payloads?
CockroachDB stores whatever your application writes. If user input is concatenated into LDAP filters without escaping, the database can hold values that later alter LDAP query semantics. Treat data from CockroachDB as untrusted when used in directory queries and apply escaping or parameterized access.