CRITICAL sql injectionaxumbasic auth

Sql Injection in Axum with Basic Auth

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

Axum is a Rust web framework. When Basic Authentication is used and credentials are validated by directly interpolating user input into SQL strings, an SQL Injection (CWE-89) path is exposed. A typical vulnerable pattern is extracting the username and password from the Basic header and concatenating them into a query such as format!("SELECT * FROM users WHERE username = '{}' AND password = '{}'", username, password). An attacker can supply username as ' OR 1=1 -- to bypass authentication or extract data. Because this check runs in an unauthenticated scan, middleBrick tests endpoints that accept Basic Auth and then probes for SQLi by injecting payloads into the credential parameters, looking for differences in responses, timing, or error messages that indicate non-parameterized queries.

SQL Injection in this context often maps to OWASP API Top 10:2023 A03:2023 — Injection, and can map to PCI-DSS and SOC2 controls. Real-world examples include authentication bypass via tautologies (e.g., ' OR '1'='1) and extracting PII or password hashes if the database connection runs with elevated privileges. middleBrick’s checks include classic injection probes and time-based techniques to confirm whether user-controlled credential data reaches the database without proper parameterization.

In a typical scan, middleBrick will send requests with crafted Basic credentials such as admin' -- and observe whether the response indicates successful authentication or an error. If the endpoint is also missing rate limiting or input validation, the attack surface is broader. This combination of weak authentication handling and dynamic SQL construction is a common finding in unauthenticated scans, and remediation requires strict use of parameterized queries and avoiding any direct string assembly for SQL.

Basic Auth-Specific Remediation in Axum — concrete code fixes

To remediate SQL Injection when using Basic Auth in Axum, ensure credentials are never concatenated into SQL strings. Use parameterized queries with a safe database client such as sqlx. Below is a secure Axum handler example that parses Basic Auth and uses parameterized SQL:

use axum::{
    extract::Request,
    http::{self, HeaderValue, StatusCode},
    response::IntoResponse,
};
use base64::decode;
use serde::Deserialize;
use sqlx::PgPool;

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

async fn validate_basic_auth(
    pool: &PgPool,
    auth_header: &str,
) -> Result {
    // Strip "Basic " prefix
    let encoded = auth_header
        .strip_prefix("Basic ")
        .ok_or((StatusCode::UNAUTHORIZED, "Missing Basic prefix".to_string()))?;
    let decoded = decode(encoded).map_err(|_| (StatusCode::UNAUTHORIZED, "Invalid base64".to_string()))?;
    let creds_str = String::from_utf8(decoded).map_err(|_| (StatusCode::UNAUTHORIZED, "Invalid UTF-8".to_string()))?;
    let parts: Vec<&str> = creds_str.splitn(2, ':').collect();
    if parts.len() != 2 {
        return Err((StatusCode::UNAUTHORIZED, "Invalid credentials format".to_string()));
    }
    Ok(Credentials {
        username: parts[0].to_string(),
        password: parts[1].to_string(),
    })
}

async fn login_handler(
    pool: web::Data,
    request: Request,
) -> Result {
    let auth_header = request
        .headers()
        .get(http::header::AUTHORIZATION)
        .and_then(|v| v.to_str().ok())
        .ok_or((StatusCode::UNAUTHORIZED, "Missing Authorization header".to_string()))?;

    let creds = validate_basic_auth(&pool, auth_header).await?;

    // Use parameterized query to prevent SQL Injection
    let user: (i32,) = sqlx::query_as("SELECT id FROM users WHERE username = $1 AND password = $2")
        .bind(&creds.username)
        .bind(&creds.password)
        .fetch_one(pool.as_ref())
        .await
        .map_err(|e| {
            if e.is_database() {
                (StatusCode::INTERNAL_SERVER_ERROR, "Database error".to_string())
            } else {
                (StatusCode::UNAUTHORIZED, "Invalid credentials".to_string())
            }
        })?;

    Ok((StatusCode::OK, format!("Authenticated as user id: {}", user.0)).into_response())
}

Key points:

  • Never use format! or string concatenation to build SQL queries with user-controlled values like Basic Auth credentials.
  • Always use parameterized queries (e.g., $1, $2 in PostgreSQL via sqlx) so the database treats input strictly as data, not executable SQL.
  • Validate and parse the Basic header carefully, returning 401 for malformed input, and avoid leaking detailed errors to the client.

Even after fixing SQL Injection, continue to enforce transport-layer encryption (HTTPS), avoid storing passwords in plaintext (use a strong adaptive hash such as Argon2), and apply rate limiting to mitigate brute-force attempts. middleBrick can verify that your endpoints no longer exhibit SQL Injection and that authentication handling follows secure patterns.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can SQL Injection via Basic Auth be detected by middleBrick?
Yes. middleBrick tests unauthenticated endpoints that use Basic Auth and attempts SQL Injection payloads in credential fields to detect whether user input is safely parameterized.
Does fixing SQL Injection require changes to the database or just the application code?
Fixing SQL Injection is primarily an application-code change: use parameterized queries and avoid string concatenation. Database configuration and least-privilege access are also important defense-in-depth measures.