HIGH data exposureaxumapi keys

Data Exposure in Axum with Api Keys

Data Exposure in Axum with Api Keys

Data exposure in Axum applications often occurs when API keys are handled without adequate safeguards, leading to their unintended leakage in logs, error messages, or client‑side artifacts. Axum, a web framework for Rust, does not inherently expose keys, but common patterns in route handling, request extensions, and logging can inadvertently surface them.

Consider an Axum handler that receives an API key via an HTTP header and forwards it to downstream services. If the key is stored in a request extension and later serialized into debug output or trace logs, it may be exposed to anyone who can view those logs. For example, using the tracing crate to log the entire request extensions map can print the key in plaintext if the developer is not careful about what is recorded.

Another exposure path is error handling. When an Axum handler panics or returns an error that includes request metadata, frameworks like axum::debug_handler or custom error responses might echo back headers or extension values. Inadequate sanitization of error payloads can leak API keys to clients or monitoring systems. This is especially risky when responses include detailed trace information in development mode but are mistakenly left verbose in production.

A third scenario involves serialization and caching. If an API key is placed into a structure that is later cached or stored—intentionally or unintentionally—and that structure is serialized (for example, with serde) into logs, metrics, or external storage, the key can persist beyond its intended lifecycle. Combined with insufficient access controls on logs or monitoring dashboards, this creates a data exposure vector where keys are readable by unauthorized users or systems.

In each case, the root cause is not Axum itself but the surrounding application logic: how keys are passed, logged, serialized, and surfaced in errors. Because middleBrick tests unauthenticated attack surfaces, it can detect endpoints that reflect API keys in responses or logs, flagging them as data exposure findings with severity and remediation guidance.

Api Keys-Specific Remediation in Axum

To prevent data exposure of API keys in Axum, ensure keys are handled as sensitive values that are never logged, echoed in errors, or serialized unnecessarily. Use dedicated secure storage for keys, limit their scope to the minimal required context, and sanitize all outputs that might include request metadata.

Below are concrete Axum code examples that demonstrate unsafe patterns and their secure alternatives.

Unsafe pattern: Logging headers including API keys

use axum::{routing::get, Router, http::HeaderMap};
use tracing::info;

async fn handler(headers: HeaderMap) -> String {
    // UNSAFE: logging headers can expose API keys
    info!(?headers, "Request received");
    "ok".to_string()
}

let app = Router::new().route("/", get(handler));

Remediation: redact sensitive headers before logging.

use axum::{routing::get, Router, http::HeaderMap};
use tracing::info;

fn redact_api_key(headers: &HeaderMap) -> impl std::fmt::Debug + '_ {
    struct RedactedHeaders<'a>(&'a HeaderMap);
    impl<'a> std::fmt::Debug for RedactedHeaders<'a> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            let mut dbg = f.debug_map();
            for (key, value) in self.0.iter() {
                let key_str = key.as_str();
                let val_str = if key_str.eq_ignore_ascii_case("authorization") || key_str.eq_ignore_ascii_case("x-api-key") {
                    "[REDACTED]"
                } else {
                    std::str::from_utf8(value).unwrap_or("")
                };
                dbg.entry(&key_str, &val_str);
            }
            dbg.finish()
        }
    }
    RedactedHeaders(headers)
}

async fn handler(headers: HeaderMap) -> String {
    info!(headers = ?redact_api_key(&headers), "Request received");
    "ok".to_string()
}

let app = Router::new().route("/", get(handler));

Unsafe pattern: Echoing headers in error responses

use axum::{routing::post, Json, http::StatusCode};
use serde::Deserialize;

#[derive(Deserialize)]
struct Payload { api_key: String }

async fn handler(Json(payload): Json) -> Result {
    // UNSAFE: returning the key in an error response
    if payload.api_key.is_empty() {
        return Err((StatusCode::BAD_REQUEST, format!("Invalid API key: {}", payload.api_key)));
    }
    Ok("success".to_string())
}

let app = Router::new().route("/check", post(handler));

Remediation: return generic error messages and avoid including key values.

use axum::{routing::post, Json, http::StatusCode};
use serde::Deserialize;

#[derive(Deserialize)]
struct Payload { api_key: String }

async fn handler(Json(payload): Json) -> Result {
    if payload.api_key.is_empty() {
        // Safe: do not echo the key value
        return Err((StatusCode::BAD_REQUEST, "Invalid API key".to_string()));
    }
    // Process the key securely without exposing it
    Ok("success".to_string())
}

let app = Router::new().route("/check", post(handler));

Best practice: Use request extensions for scoped key access

use axum::{routing::get, Router, extract::Extension};
use std::sync::Arc;

struct Config { api_key: String }

async fn handler(Extension(cfg): Extension>) -> String {
    // Use cfg.api_key internally without logging or exposing it
    if cfg.api_key.is_empty() {
        return "forbidden".to_string();
    }
    "authorized".to_string()
}

let config = Arc::new(Config { api_key: "super-secret".to_string() });
let app = Router::new()
    .layer(Extension(config))
    .route("/", get(handler));

By keeping API keys in controlled extension state and avoiding their serialization or inclusion in logs and error messages, you significantly reduce the risk of data exposure in Axum services. middleBrick can identify endpoints that reflect sensitive values by scanning unauthenticated attack surfaces and will provide prioritized findings with severity levels and remediation steps.

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

Can middleBrick detect API keys leaked in error responses?
Yes. middleBrick runs multiple checks including Data Exposure that can identify endpoints reflecting sensitive values such as API keys in responses or logs, and it reports findings with severity and remediation guidance.
Does Axum itself cause API key exposure, or is it always an application logic issue?
Axum does not inherently expose API keys. Exposure typically results from how keys are logged, echoed in errors, serialized, or cached. Secure handling patterns in Axum—such as redacting headers and avoiding key reflection in errors—prevent data exposure.