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,$2in PostgreSQL viasqlx) 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 ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |