HIGH axumrustssrf cloud metadata

Ssrf Cloud Metadata in Axum (Rust)

Ssrf Cloud Metadata in Axum with Rust — how this specific combination creates or exposes the vulnerability

Server-Side Request Forgery (SSRF) against cloud metadata services occurs when an Axum-based Rust service accepts an untrusted URL and uses it to make outbound HTTP requests. In cloud environments, the metadata service (e.g., 169.254.169.254 on many platforms) is often reachable only from within the host VM. An attacker who can influence the target URL may force the application to fetch sensitive cloud metadata that would not be accessible otherwise.

With Axum, a handler that forwards or fetches from a user-supplied URL can inadvertently reach the metadata service if the runtime environment lacks proper egress filtering. For example, an Axum route that uses reqwest to call a URL provided via a query parameter may resolve to the metadata endpoint if the attacker supplies http://169.254.169.254/latest/meta-data/ as the target. Because the application is running inside the cloud host and the metadata service is bound to the link-local address, the request succeeds and returns sensitive data such as instance identity, network configuration, and IAM credentials.

SSRF in this context is not about consuming an arbitrary external API; it is about the application acting as a proxy into the host environment. Axum does not enforce where a request can go, so developers must validate and restrict targets. Common patterns that increase risk include using a pass-through URL to introspect a service, dynamically constructing endpoints from user input, or allowing batch operations that iterate over user-provided origins. When combined with overly permissive network configurations, an SSRF against cloud metadata can lead to information disclosure, lateral movement, or privilege escalation.

To detect such issues, middleBrick scans an Axum endpoint for SSRF by supplying a crafted URL that points to the cloud metadata address. The scan checks whether the application follows the supplied target and returns metadata content. This helps identify whether input validation and egress controls are sufficient to prevent an unauthenticated attacker from reaching internal services.

Rust-Specific Remediation in Axum — concrete code fixes

Mitigating SSRF in Axum requires explicit allowlisting of destinations, rejecting private and reserved IPs, and avoiding any forwarding to metadata addresses. Below are concrete, idiomatic Rust examples that demonstrate safe patterns when building Axum handlers.

First, define a destination allowlist and a validation function that rejects private and reserved ranges, as well as the metadata IP 169.254.169.254. This approach ensures that even if a user-supplied URL is provided, the application will not make requests to sensitive internal endpoints.

use std::net::IpAddr;
use url::Url;

fn is_allowed_host(host: &str) -> bool {
    // Explicitly allowed hostnames or domains
    let allowed = ["api.example.com", "data.example.com"];
    if allowed.contains(&host) {
        return true;
    }
    // Parse as IP to check ranges
    if let Ok(ip) = host.parse::() {
        return !is_private_or_reserved(&ip);
    }
    false
}

fn is_private_or_reserved(ip: &IpAddr) -> bool {
    match ip {
        IpAddr::V4(v4) => {
            // Private RFC1918
            v4.is_private()
                || v4.is_loopback()
                || v4.is_link_local()
                || v4.is_documentation()
                || v4.octets()[0] == 100 && (v4.octets()[1] & 0b1100_0000) == 0b0100_0000 // 100.64.0.0/10
                || ip == &"169.254.169.254".parse().unwrap() // Cloud metadata
        }
        IpAddr::V6(v6) => {
            v6.is_loopback()
                || v6.is_link_local()
                || v6.is_unique_local()
                || v6.is_documentation()
        }
    }
}

Next, integrate this validation into an Axum handler. Do not forward requests; instead, use the allowed host to construct a safe request. If you must accept a path, ensure it is appended only to a pre-approved base URL.

use axum::{
    extract::Query,
    response::IntoResponse,
    routing::get,
    Router,
};
use reqwest::Client;
use std::net::SocketAddr;

#[derive(serde::Deserialize)]
struct FetchParams {
    path: String, // e.g., "users/123"
}

async fn fetch_user(
    Query(params): Query,
) -> Result {
    // Allowlist base — never concatenate user input directly to a domain
    let base = "https://api.example.com";
    if !is_allowed_host(&url::Url::parse(base).unwrap().host_str().unwrap_or("")) {
        return Err((axum::http::StatusCode::FORBIDDEN, "destination not allowed".into()));
    }

    let url = format!("{}/{}", base, params.path);
    let client = Client::new();
    match client.get(&url).send().await {
        Ok(resp) => {
            let text = resp.text().await.map_err(|e| (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
            Ok(text.into_response())
        }
        Err(e) => Err((axum::http::StatusCode::BAD_GATEWAY, e.to_string())),
    }
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/user", get(fetch_user));
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

For dynamic APIs, prefer a curated destination map instead of raw user input. If you must inspect arbitrary endpoints in a controlled environment (e.g., internal service discovery), enforce strict network policies and disable outbound access to 169.254.169.254 at the infrastructure level. middleBrick can validate that your runtime configuration and endpoint definitions do not permit metadata leaks by scanning your Axum service and flagging SSRF-prone patterns.

Frequently Asked Questions

Can SSRF be exploited through Axum middleware that modifies requests?
Yes, if middleware constructs outbound URLs from unchecked user input and forwards them, it can reach cloud metadata. Validate and allowlist all destinations in middleware as you would in handlers.
Does using a service mesh remove the need for SSRF validation in Axum?
A service mesh can restrict egress, but application-layer validation remains necessary. An SSRF bug in the app can still target internal mesh endpoints or metadata if policies are misconfigured.