HIGH log injectionaxumapi keys

Log Injection in Axum with Api Keys

Log Injection in Axum with Api Keys — how this specific combination creates or exposes the vulnerability

Log injection occurs when untrusted input is written directly into log entries without sanitization, enabling attackers to forge log lines, obscure real events, or inject additional structured data into logging streams. In Axum, a common pattern is to log incoming requests together with metadata such as API keys to help with debugging, auditing, and operational monitoring. While including an API key in logs can be useful for traceability, failing to validate or sanitize the key value and the surrounding log message creates a path for log injection.

Consider an Axum handler that logs the API key directly from a header:

use axum::{
    async_trait,
    extract::State,
    response::IntoResponse,
    routing::get,
    Json, Router,
};
use std::net::SocketAddr;

struct AppState;

async fn handler(
    State(_state): State<AppState>,
    // Extract API key from header
    api_key: Option<axum::extract::Header<axum::http::header::Authorization>>,
) -> impl IntoResponse {
    if let Some(key_header) = api_key {
        let key_str = key_header.to_string(); // potentially unsafe if key contains newlines or control chars
        // Log injection risk: key_str may contain newlines or structured delimiters
        tracing::info!("api_key={} request_path={}", key_str, "GET /health");
    }
    // ... handle request
}

If an attacker sends an API key containing newline characters (e.g., evil [extra="injected"]), the log line can be split into multiple logical entries, corrupting log structure and potentially allowing injection of fake log events. Similarly, if the key includes characters like ", =, or structured separators used by the logging pipeline, an attacker can alter how logs are parsed or visualized. This is especially relevant when logs are ingested by SIEMs or monitoring tools that rely on consistent delimiters to parse fields.

In the context of middleBrick’s scans, the LLM/AI Security and Unsafe Consumption checks highlight risks around uncontrolled outputs, while the Data Exposure and Property Authorization checks surface how poorly formed logs can leak sensitive identifiers. A log-injected API key may also be reflected elsewhere (for example in error messages or admin dashboards), increasing the chance of sensitive data exposure across components.

Api Keys-Specific Remediation in Axum — concrete code fixes

Remediation focuses on sanitizing the API key before it reaches log statements and ensuring structured, safe logging practices. Do not log raw API keys when possible; if you must log them, normalize and escape problematic characters, and avoid interpolating untrusted strings directly into log formats.

1) Redact or hash API keys in logs:

use axum::{
    async_trait,
    extract::State,
    response::IntoResponse,
    routing::get,
    Json, Router,
};
use sha2::{Sha256, Digest};

async fn handler(
    State(_state): State<AppState>,
    api_key: Option<axum::extract::Header<axum::http::header::Authorization>>,
) -> impl IntoResponse {
    if let Some(key_header) = api_key {
        let key_str = key_header.to_string();
        // Hash the key for safe logging
        let mut hasher = Sha256::new();
        hasher.update(key_str.as_bytes());
        let key_hash = hex::encode(hasher.finalize());
        tracing::info!(api_key_hash=%key_hash, request_path="GET /health");
    }
    // ... handle request
}

2) Validate and sanitize before logging (if you must store the raw key fragment):

fn safe_log_api_key(raw: &str) -> String {
    // Replace newlines and carriage returns, limit length, and escape quotes
    let trimmed = raw.trim();
    let no_newlines = trimmed.replace('\n', "\\n").replace('\r', "\\r");
    // Truncate to a sensible length to avoid log bombs
    if no_newlines.len() > 128 {
        format!("{}...", &no_newlines[..128])
    } else {
        no_newlines
    }
}

async fn handler(
    State(_state): State<AppState>,
    api_key: Option<axum::extract::Header<axum::http::header::Authorization>>,
) -> impl IntoResponse {
    if let Some(key_header) = api_key {
        let safe_key = safe_log_api_key(&key_header.to_string());
        tracing::info!(api_key=safe_key, request_path="GET /health");
    }
    // ... handle request
}

3) Use structured logging with typed fields and avoid concatenating raw strings:

// Prefer this pattern to string interpolation
tracing::info!(target: "api_requests", api_key_present=true, method=%method, path=%path);

By combining redaction, input validation, and structured logging, you reduce the risk that an API key will corrupt log events or enable log injection. middleBrick’s scans can verify whether endpoints leak raw keys in responses or logs and map findings to relevant checks such as Data Exposure and Property Authorization.

Frequently Asked Questions

Can log injection via API keys affect compliance assessments?
Yes. If API keys are logged unsanitized, findings may map to data exposure and integrity controls in frameworks such as OWASP API Top 10, SOC2, and PCI-DSS, because corrupted logs reduce audit reliability and may obscure malicious activity.
Does middleBrick fix log injection issues automatically?
No. middleBrick detects and reports potential log injection findings with remediation guidance. It does not modify code or block requests; developers must apply the suggested fixes in their Axum services.