HIGH ssrfaxumapi keys

Ssrf in Axum with Api Keys

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

Server-Side Request Forgery (SSRF) in an Axum service that uses API keys for outbound calls can occur when user-controlled data influences the request destination after an API key is attached. In a typical pattern, a client sends an internal token or key to Axum (for example via an Authorization: Bearer header), and the server uses that key to call another service. If the target URL for that outbound call is derived from user input without strict validation, an attacker can coerce the server into making arbitrary internal or external requests, potentially reaching metadata services like 169.254.169.254 or internal Kubernetes endpoints.

Consider an Axum handler that accepts a url field and an api_key field, then forwards a request to the provided URL while adding the key as a header. Without strict allowlisting and parsing, an attacker can supply a URL such as http://169.254.169.254/latest/meta-data/iam/security-credentials/. The server makes the request, attaches the API key in a header, and returns sensitive cloud metadata. Even if the API key is intended for outbound authentication, SSRF exposes it in contexts the key was never meant to access, and it may also reveal internal services that rely on key-based auth but lack additional network controls.

In a black-box scan, middleBrick tests SSRF by submitting candidate URLs that probe internal endpoints and cloud metadata services. When an Axum endpoint reflects or redirects to internal destinations and includes API key headers in those requests, findings may map to the SSRF control and expose an unauthenticated attack surface. Because Axum applications often integrate multiple services, a vulnerable handler can chain SSRF with API key misuse, amplifying the impact by exposing credentials that would otherwise remain scoped to specific outbound integrations.

Api Keys-Specific Remediation in Axum — concrete code fixes

To mitigate SSRF in Axum when using API keys, ensure that any user-influenced URL is strictly validated and that API keys are only attached to known, allowlisted destinations. Use strong URL parsing and allowlisting rather than host substring matching. Below is a safe Axum handler that accepts a URL path parameter and an API key header, validates the path against a predefined set of allowed hosts, and then makes an authenticated request only to those destinations.

use axum::{routing::get, Router, extract::Query, http::HeaderMap};
use serde::Deserialize;
use reqwest::Client;
use std::net::SocketAddr;

#[derive(Deserialize)]
struct ProxyQuery {
    host: String,
    path: String,
}

async fn proxy_handler(
    Query(query): Query,
    headers: HeaderMap,
    client: axum::extract::State<Client>
) -> Result<String, (axum::http::StatusCode, String)> {
    // Strict allowlist: only these hosts are valid targets
    const ALLOWED_HOSTS: &[&str] = "api.example.com", "internal.service.local";
    if !ALLOWED_HOSTS.contains(&query.host.as_str()) {
        return Err((axum::http::StatusCode::BAD_REQUEST, "Host not allowed".into()));
    }

    // Build the full URL safely from validated components
    let url = format!("https://{}/{}", query.host, query.path);
    let request = client.get(&url)
        .headers(headers.clone())
        .build()
        .map_err(|e| (axum::http::StatusCode::BAD_REQUEST, e.to_string()))?;

    let response = client.execute(request).await
        .map_err(|e| (axum::http::StatusCode::BAD_REQUEST, e.to_string()))?;
    let body = response.text().await.map_err(|e| (axum::http::StatusCode::BAD_REQUEST, e.to_string()))?;
    Ok(body)
}

#[tokio::main]
async fn main() {
    let client = Client::new();
    let app = Router::new()
        .route("/proxy", get(proxy_handler))
        .with_state(client);

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

This approach ensures that even if an attacker injects a malicious URL, the request fails early unless the host is explicitly allowed. API keys passed in headers remain scoped to trusted endpoints, reducing the risk of credential leakage via SSRF. For broader coverage, middleBrick’s scans validate SSRF and API key handling patterns; the Pro plan supports continuous monitoring so changes to handlers are flagged before deployment, and the GitHub Action can fail builds if risky URL construction is detected in new code.

Related CWEs: ssrf

CWE IDNameSeverity
CWE-918Server-Side Request Forgery (SSRF) CRITICAL
CWE-441Unintended Proxy or Intermediary (Confused Deputy) HIGH

Frequently Asked Questions

Can SSRF in Axum expose API keys even if the keys are stored as environment variables?
Yes. If user input determines the request destination and the server attaches API key headers before making that request, SSRF can cause the server to call internal or external endpoints, potentially leaking the keys in logs or responses.
Does enabling TLS on outbound requests prevent SSRR in Axum?
No. Transport-layer encryption does not prevent SSRF; it only protects the content in transit. The core issue is uncontrolled URL resolution, which must be addressed through strict allowlisting and input validation.