HIGH cors wildcardaxumbasic auth

Cors Wildcard in Axum with Basic Auth

Cors Wildcard in Axum with Basic Auth — how this specific combination creates or exposes the vulnerability

A wildcard CORS policy (Access-Control-Allow-Origin: *) combined with Axum routes that use HTTP Basic Auth can unintentionally expose authenticated endpoints to any origin. When credentials are required, browsers treat wildcard origins as insecure and will reject the response, but server-side code may still process the request if CORS handling is not aligned with authentication requirements.

In Axum, a route that enforces Basic Auth via middleware can still allow cross-origin requests if the CORS layer permits *. An attacker can craft a web page hosted on a malicious domain that sends authenticated requests using stored credentials (e.g., a session cookie or manually entered username/password). The browser’s CORS checks may block JavaScript from reading the response, but the server processes the request, potentially leading to unauthorized actions or information disclosure.

Consider an Axum endpoint that relies on Basic Auth headers and also exposes CORS headers with a wildcard. A preflight request (OPTIONS) with Origin: https://evil.com and Access-Control-Request-Method: POST may receive a permissive response, signaling that any origin is allowed. If the route does not validate the origin against an allowlist, the endpoint becomes a vector for cross-origin misuse, even if the browser blocks frontend access to the response.

This combination is especially risky when the Basic Auth credentials are static or reused across services, as attackers can probe the exposed endpoint from arbitrary origins. The vulnerability is not in Basic Auth itself, but in the lack of origin validation paired with permissive CORS rules. For endpoints that require credentials, CORS should restrict origins explicitly and avoid wildcards to prevent unauthorized cross-origin usage.

Basic Auth-Specific Remediation in Axum — concrete code fixes

To secure Axum routes that use Basic Auth, apply CORS policies that restrict origins and ensure authentication checks occur before any sensitive logic. Below is a minimal, working example that combines middleware for Basic Auth with a strict CORS configuration.

use axum::{
    async_trait, body::Body, extract::FromRequest, http::request::Parts, middleware, response::IntoResponse,
    routing::post, Router,
};
use headers::{authorization::Authorization, Basic};
use std::net::SocketAddr;
use tower_http::cors::{CorsLayer, Any};

struct Authenticated;

#[async_trait]
impl FromRequest<S> for Authenticated
where
    S: Send + Sync,
{
    type Rejection = ();

    async fn from_request(req: Parts, _state: &S) -> Result<Self, Self::Rejection> {
        let headers = req.headers;
        let auth_header = headers.get("authorization")
            .and_then(|h| h.to_str().ok())
            .and_then(|s| s.strip_prefix("Basic "))
            .unwrap_or("");

        // Decode credentials and validate (example uses a hardcoded check)
        let decoded = base64::decode(auth_header).map_err(|_| ())?;
        let creds = String::from_utf8(decoded).map_err(|_| ())?;
        if creds == "admin:secret" {
            Ok(Authenticated)
        } else {
            Err(())
        }
    }
}

async fn handler() -> impl IntoResponse {
    "Authorized"
}

#[tokio::main]
async fn main() {
    let cors = CorsLayer::new()
        .allow_origin(Any.except_localhost()) // restrictive example; use a specific origin in production
        .allow_methods(vec!["POST", "OPTIONS"])
        .allow_headers(vec![headers::AUTHORIZATION]);

    let app = Router::new()
        .route("/secure", post(handler))
        .layer(middleware::from_fn(|req, next| async move {
            // Authentication check
            let authenticated = Authenticated::from_request(req.parts(), &()).await;
            if authenticated.is_err() {
                return Err((http::StatusCode::UNAUTHORIZED, "Invalid credentials")).into_response();
            }
            next.run(req).await
        }))
        .layer(cors);

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

Key points in this remediation:

  • Use an allowlist for origins instead of a wildcard when credentials are involved.
  • Validate credentials before processing the request, and return 401 for missing or invalid Basic Auth.
  • Include Authorization in CORS allowed headers so browsers handle credentialed requests correctly.

If your API is also exposed through tools like the middleBrick CLI (middlebrick scan <url>) or integrated into CI/CD via the GitHub Action, these configurations will be surfaced in scan findings, helping you detect permissive CORS rules and weak authentication practices.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Why does a wildcard CORS policy become risky when Basic Auth is used?
A wildcard CORS policy allows any origin to make requests. When endpoints also require credentials (e.g., Basic Auth), browsers may block frontend JavaScript from reading responses, but server-side processing can still occur. This enables cross-origin requests that may lead to unauthorized actions if origin validation is missing.
How can I test my Axum Basic Auth + CORS configuration with security scanning tools?
You can use the middleBrick CLI to scan your endpoint: middlebrick scan <url>. The scan will report CORS misconfigurations and authentication issues, and you can integrate the GitHub Action to fail builds if the risk score drops below your chosen threshold.