HIGH ssrf server sideaxumjwt tokens

Ssrf Server Side in Axum with Jwt Tokens

Ssrf Server Side in Axum with Jwt Tokens — how this specific combination creates or exposes the vulnerability

Server-side request forgery (SSRF) in an Axum service that validates JWT tokens can occur when an endpoint that requires a valid token also accepts a user-supplied URL and performs an outbound HTTP request. Even though JWT validation ensures the caller is authenticated and their claims are verified, the trust boundary does not extend to the destination of the outbound request. If the application uses the caller-supplied URL to fetch resources without strict allowlisting, an attacker can coerce the server into making arbitrary internal or external requests. This becomes especially risky when the JWT contains elevated scopes or roles that the application mistakenly trusts when deciding whether the request to the target URL is permitted.

In Axum, a typical pattern is to extract a bearer token via an extractor, validate it, and then proceed to business logic that may call external services. Consider an endpoint that accepts a url query or body parameter to retrieve remote metadata. If the developer assumes that a valid JWT implies safe intent, they may forward the provided URL to an HTTP client without restricting hostnames, ports, or schemes. An attacker can supply an internal address like http://169.254.169.254/latest/meta-data/iam/security-credentials/ (AWS instance metadata) or internal Kubernetes services, leading to sensitive data exposure. SSRF can also pivot to internal Redis, MongoDB, or gRPC endpoints that are not exposed publicly but are reachable from the server network.

JWT tokens themselves can inadvertently aid SSRF when custom claims or the token payload are used to construct URLs or influence routing decisions. For example, if a redirect_uri claim is reflected into an outbound request without strict validation, or if the token’s iss or aud fields are used to build target URLs, the server may be tricked into sending requests to attacker-controlled endpoints. MiddleBrick’s LLM/AI Security checks include system prompt leakage detection and active prompt injection testing, which are useful for ensuring that LLM integrations do not inadvertently expose internal URLs or tokens via generated output in AI-assisted API workflows.

Another subtle risk arises when Axum routes are conditionally composed based on JWT scopes. An attacker with a low-privilege token might exploit overly permissive route guards to trigger server-side fetches to internal services by manipulating URL templates or query parameters. Because SSRF is about the server making unauthorized requests, the presence of JWT validation does not mitigate the core issue: lack of network-level restrictions on outbound calls. Out-of-the-box black-box scanning by middleBrick tests these unauthenticated attack surfaces, including endpoints that require tokens but still accept arbitrary URLs, to surface SSRF risks without needing credentials.

Jwt Tokens-Specific Remediation in Axum — concrete code fixes

To remediate SSRF in Axum while using JWT tokens, enforce strict validation of any user-controlled URL inputs and avoid using token-derived data to construct target endpoints. Do not rely on token validation alone to ensure request safety. Instead, apply allowlisting for hostnames and ports, reject non-HTTP(S) schemes, and isolate outbound traffic to known internal networks when necessary.

Below is a concrete Axum example that demonstrates secure handling of a user-supplied URL when JWT authentication is required. The handler extracts the token for validation, then validates the URL against a strict allowlist before performing the outbound request.

use axum::{
    async_trait,
    extract::FromRequest,
    routing::get,
    Router,
};
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
use std::net::SocketAddr;
use reqwest::Client;

#[derive(Debug, serde::Deserialize)]
struct Claims {
    sub: String,
    scopes: Vec<String>,
}

async fn validate_token(token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
    let key = DecodingKey::from_secret(b"secret");
    let mut validation = Validation::new(Algorithm::HS256);
    validation.validate_exp = true;
    decode<Claims>(token, &key, &validation).map(|t| t.claims)
}

async fn fetch_metadata(url: String) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
    // Strict allowlist: only specific internal hosts when necessary
    let allowed_hosts = ["127.0.0.1", "169.254.169.254"]; // example: limited to metadata service
    let parsed = url::Url::parse(&url)?;
    if !["http", "https"].contains(&parsed.scheme()) {
        return Err("unsupported scheme".into());
    }
    let host = parsed.host_str().ok_or("missing host")?;
    if !allowed_hosts.contains(&host) {
        return Err("host not allowed".into());
    }
    let client = Client::new();
    let resp = client.get(url).send().await?;
    let body = resp.text().await?;
    Ok(body)
}

async fn handler(
    token: String,
    url: String,
) -> Result<impl Into<axum::response::Response>, (axum::http::StatusCode, String)> {
    let _claims = validate_token(&token).map_err(|_| (axum::http::StatusCode::UNAUTHORIZED, "invalid token"))?;
    let data = fetch_metadata(url).await.map_err(|e| (axum::http::StatusCode::BAD_REQUEST, e.to_string()))?;
    Ok(axum::response::IntoResponse::into_response(data))
}

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

Key points in this example:

  • JWT validation is performed first to establish identity and claims, but it does not authorize arbitrary outbound requests.
  • The fetch_metadata function enforces an allowlist of hosts and rejects non-HTTP(S) schemes, preventing redirection to internal cloud metadata services or private endpoints.
  • By combining token validation with strict network-level controls, you reduce the risk of SSRF while still enabling legitimate external calls.

For broader protection, integrate middleBrick’s GitHub Action to add API security checks to your CI/CD pipeline, ensuring that SSRF-prone patterns are flagged before deployment. The CLI tool (middlebrick scan <url>) can also be used locally to scan endpoints that use JWT tokens and identify SSRF risks during development.

Frequently Asked Questions

Does JWT validation prevent SSRF in Axum APIs?
No. JWT validation confirms the caller’s identity and claims but does not restrict the server’s outbound network destinations. SSRF mitigation requires explicit allowlisting of hosts, schemes, and ports for any user-controlled URLs.
Can middleBrick detect SSRF in endpoints that require JWT tokens?
middleBrick scans the unauthenticated attack surface and can identify SSRF-prone patterns in Axum APIs, including endpoints that require tokens but accept arbitrary URLs. Use the CLI (middlebrick scan <url>) or GitHub Action to integrate checks into your workflow.