Zip Slip in Axum with Basic Auth
Zip Slip in Axum with Basic Auth — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when an archive extraction uses user-supplied paths without proper sanitization, allowing files to be written outside the intended directory. In Axum, a Rust web framework, this risk can emerge when an endpoint accepts file uploads or archive downloads and constructs filesystem paths by concatenating a base directory with a filename from user input. If the input contains sequences like ../, an attacker can traverse parent directories and overwrite arbitrary files on the server.
When Basic Auth is used in Axum, it typically involves extracting credentials from the Authorization header, parsing them, and deciding whether to proceed with the request. The presence of Basic Auth does not inherently protect against Zip Slip; if authentication succeeds, the application may still pass user-controlled data directly into extraction logic. This creates a two-stage exposure: first, authentication grants access; second, insufficient path validation in the handler permits traversal. For example, an authenticated user could supply a malicious archive containing paths like ../../../etc/passwd, and if the handler writes extracted files without normalization or restriction, sensitive files may be overwritten or configuration files may be corrupted.
In practice, this combination is problematic because developers may assume that authentication enforces boundaries, but the vulnerability lives in the file handling code, not the authentication layer. An endpoint that requires Basic Auth might still call a function like ZipArchive::extract with user-provided filenames, and if the archive includes crafted entries, traversal occurs. MiddleBrick’s checks for BOLA/IDOR and Unsafe Consumption are relevant here because they test whether authenticated and unauthenticated behaviors expose path traversal risks, and they highlight how authentication headers do not mitigate improper archive handling.
To detect this during a scan, middleBrick runs unauthentiated probes and authenticated checks where credentials are supplied via Basic Auth headers. It examines whether authentication gates change file handling behavior and whether archives or file paths processed after login remain vulnerable. The scanner’s inventory management and Unsafe Consumption checks specifically look for missing path sanitization and unsafe extraction patterns, which are common in Axum services that integrate uploads or external archives without rigorous validation.
Basic Auth-Specific Remediation in Axum — concrete code fixes
Securing Axum endpoints that use Basic Auth against Zip Slip requires validating and sanitizing any user-controlled path components before using them in filesystem operations. Below are concrete code examples that demonstrate a safe approach while preserving Basic Auth for access control.
First, implement a path sanitization utility that prevents directory traversal. This function normalizes a path and ensures it remains within a designated base directory:
use std::path::{Path, PathBuf};
fn safe_path(base: &Path, input: &str) -> Result {
let mut path = base.to_path_buf();
for component in Path::new(input).components() {
match component {
std::path::Component::Normal(c) => path.push(c),
_ => return Err('Invalid path component'),
}
}
if path.starts_with(base) {
Ok(path)
} else {
Err('Path traversal detected')
}
}
Next, apply this in an Axum handler that uses Basic Auth. The handler extracts credentials, validates them, and then processes a filename safely before extraction:
use axum::{routing::post, Router};
use base64::Engine;
use std::net::SocketAddr;
async fn handle_upload(
headers: axum::http::HeaderMap,
// Assume body contains a filename and archive bytes
filename: String,
) -> Result {
// Basic Auth extraction
let auth_header = headers.get("authorization").ok_or((axum::http::StatusCode::UNAUTHORIZED, "Missing auth"))?;
let auth_str = auth_header.to_str().map_err(|_| (axum::http::StatusCode::UNAUTHORIZED, "Invalid auth format"))?;
if !auth_str.starts_with("Basic ") {
return Err((axum::http::StatusCode::UNAUTHORIZED, "Invalid auth scheme"));
}
let encoded = auth_str.trim_start_matches("Basic ");
let decoded = base64::engine::general_purpose::STANDARD.decode(encoded).map_err(|_| (axum::http::StatusCode::UNAUTHORIZED, "Invalid base64"))?;
let creds = String::from_utf8(decoded).map_err(|_| (axum::http::StatusCode::UNAUTHORIZED, "Invalid credentials"))?;
// Simple check — in production use constant-time compare and proper user management
if creds != "admin:secret" {
return Err((axum::http::StatusCode::UNAUTHORIZED, "Invalid credentials"));
}
// Safe path construction
let base = std::path::Path::new("/safe/uploads");
let safe = safe_path(base, &filename).map_err(|e| (axum::http::StatusCode::BAD_REQUEST, e.to_string()))?;
// Proceed with extraction using safe path
// e.g., let mut archive = zip::ZipArchive::new(file)?;
// archive.extract(safe.parent().unwrap())?;
Ok("OK".to_string())
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/upload", post(handle_upload));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();
}
This example shows how Basic Auth is validated before any file operations and how path traversal is prevented by rejecting .. components and ensuring the resolved path remains inside the base directory. MiddleBrick’s checks for BFLA/Privilege Escalation and Property Authorization can verify that authentication gates are enforced and that path handling does not leak sensitive files.
Frequently Asked Questions
Does using Basic Auth in Axum prevent Zip Slip vulnerabilities?
What specific remediation steps should be applied in Axum to mitigate Zip Slip when Basic Auth is used?
.. or absolute paths, ensure resolved paths remain within a designated base directory, and apply these checks in handlers regardless of authentication status. Use utilities that check path ancestry before filesystem operations.