HIGH path traversalaxumbasic auth

Path Traversal in Axum with Basic Auth

Path Traversal in Axum with Basic Auth — how this specific combination creates or exposes the vulnerability

Path Traversal occurs when user-controlled input used to resolve file paths allows directory traversal sequences (e.g., ../) to escape a intended directory. In Axum, this commonly arises when route parameters or query values are directly passed to filesystem operations such as tokio::fs::read or when building file paths for static assets. Combining this with Basic Auth can expose subtle risks: the authentication layer may log or reflect credentials in a way that aids an attacker while the application itself serves files based on manipulated paths.

For example, an endpoint like /files/{filename} that resolves paths relative to a base directory can be abused if the filename parameter includes sequences like ../../etc/passwd. Even when Basic Auth is enforced via middleware, a misconfigured route or permissive CORS/preflight behavior can allow unauthenticated or partially authenticated traversal attempts to reach filesystem logic. Moreover, if error messages from Axum handlers leak absolute paths or directory structures, they can guide an attacker to refine traversal patterns. Because middleBrick tests unauthenticated attack surfaces, it can detect endpoints where traversal is possible despite Basic Auth being present, highlighting mismatches between authentication enforcement and input validation.

During a scan, middleBrick evaluates whether path parameters are properly sanitized and whether framework-level guards prevent directory escapes. Findings may include missing validation, overly permissive route patterns, or unsafe use of libraries like tokio::fs that do not canonicalize paths. The LLM/AI Security checks additionally probe whether authentication prompts or error responses can be abused to reveal hints useful for traversal attacks, ensuring coverage beyond conventional checks.

Basic Auth-Specific Remediation in Axum — concrete code fixes

Secure handling in Axum requires strict input validation, path canonicalization, and careful use of authentication middleware. Avoid concatenating user input directly into filesystem paths. Instead, resolve paths against a strict base directory and ensure the resolved path remains within that directory. Use middleware to enforce Basic Auth and validate credentials before allowing access to file-serving routes.

Secure Basic Auth middleware in Axum

Implement a middleware layer that validates Basic Auth credentials and attaches identity information to requests. The following example shows a minimal, production-grade approach using tower::Service and axum::extract::Request:

use axum::{http::Request, async_trait, extract::FromRequestParts};
use axum::extract::request::Parts;
use std::convert::Infallible;
use headers::authorization::Authorization;
use headers::Authorization as AuthHeader;
use std::net::SocketAddr;
use tower_http::auth::Authorization as TowerAuth;

struct Authenticated;

#[async_trait]
impl FromRequestParts for Authenticated
where
    S: Send + Sync,
{
    type Rejection = (http::StatusCode, &'static str);

    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result {
        let auth_header = parts.headers.get("authorization")
            .and_then(|h| h.to_str().ok())
            .and_then(|s| s.strip_prefix("Basic "))
            .ok_or((http::StatusCode::UNAUTHORIZED, "missing or invalid auth"))?;

        // In real code, decode and validate credentials securely
        let decoded = base64::decode(auth_header).map_err(|_| (http::StatusCode::UNAUTHORIZED, "invalid encoding"))?;
        let creds = String::from_utf8(decoded).map_err(|_| (http::StatusCode::UNAUTHORIZED, "invalid credentials"))?;
        let parts: Vec<&str> = creds.splitn(2, ':').collect();
        if parts.len() != 2 || parts[0] != "admin" || parts[1] != "secret" {
            return Err((http::StatusCode::UNAUTHORIZED, "bad credentials"));
        }
        Ok(Authenticated)
    }
}

async fn file_handler(
    Authenticated(_auth): Authenticated,
    axum::extract::Path(filename): axum::extract::Path,
) -> Result {
    // Safe path resolution follows
}

Secure path resolution in file-handling routes

After authentication, resolve user input against a predefined base directory and canonicalize the result to prevent traversal. Use std::path::Path and canonicalize to ensure the final path is absolute and contained. The following handler demonstrates a safe pattern:

use axum::response::IntoResponse;
use std::path::{Path, PathBuf};
use tokio::fs::File;
use tokio::io::AsyncReadExt;

async fn serve_file(filename: String) -> Result {
    let base = Path::new("/safe/base/directory");
    // Normalize and prevent traversal
    let mut path = base.join(&filename);
    path = path.canonicalize().map_err(|_| (http::StatusCode::NOT_FOUND, "file not found"))?;

    // Ensure the resolved path is still within the base directory
    if !path.starts_with(base) {
        return Err((http::StatusCode::FORBIDDEN, "access denied"));
    }

    let mut file = File::open(path).await.map_err(|_| (http::StatusCode::NOT_FOUND, "file not found"))?;
    let mut contents = Vec::new();
    file.read_to_end(&mut contents).await.map_err(|_| (http::StatusCode::INTERNAL_SERVER_ERROR, "read error"))?;
    Ok(contents)
}

// Combined route with authentication and safe path handling
async fn protected_file_route(
    auth: Authenticated,
    Path(filename): Path,
) -> Result {
    serve_file(filename).await
}

Key practices include:

  • Always canonicalize user-provided paths before using them in filesystem operations.
  • Explicitly check that resolved paths start with the intended base directory.
  • Return generic error messages to avoid leaking filesystem details in responses.

middleBrick’s checks for Path Traversal and Authentication align with these patterns, flagging missing canonicalization or improper validation even when Basic Auth is present.

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 Basic Auth alone prevent path traversal attacks in Axum?
No. Basic Auth provides authentication but does not sanitize or validate file path inputs. Path Traversal depends on how route parameters are resolved; attackers can still use sequences like ../ unless you explicitly validate and canonicalize paths in your handlers.
What should I validate when serving files from user input in Axum?
Validate and sanitize all user input: reject or encode traversal sequences, resolve paths against a strict base directory using Path::join, canonicalize the result, and confirm the final path remains within the base directory. Also avoid exposing filesystem details in error responses.