HIGH ssrfactixjwt tokens

Ssrf in Actix with Jwt Tokens

Ssrf in Actix with Jwt Tokens — how this specific combination creates or exposes the validation gap

Server-Side Request Forgery (SSRF) in Actix applications that also handle JWT tokens arises when an API endpoint accepts a user-supplied URL, performs an outbound HTTP request on behalf of the caller, and either fails to validate the target or inadvertently includes authorization information in a way that exposes internal resources. JWT tokens are often used to carry authentication or identity claims; if an endpoint uses those tokens to authorize access to internal services (e.g., calling another microservice with the token as a bearer credential) without strict destination validation, SSRF can occur.

For example, consider an Actix endpoint that accepts a target_url parameter and forwards an authenticated request using a JWT extracted from an incoming Authorization header. If the developer does not enforce a strict allowlist of hostnames or schemes, an attacker can supply a URL like http://169.254.169.254/latest/meta-data/iam/security-credentials/ (AWS instance metadata). The Actix service, carrying the original JWT as a bearer token, forwards the request internally, potentially leaking sensitive metadata or cloud instance roles. Even if the JWT is validated for signature and claims, the SSRF bypasses intended access boundaries because the token is used downstream without additional network controls.

In an OpenAPI 3.0 specification, such a route might appear permissive by accepting any string for a redirect or callback URL. Runtime SSRF checks in middleBrick scan for these patterns by correlating the OpenAPI definition with observed behavior: the scanner submits probe URLs (including internal IPs, cloud metadata endpoints, and SSRF-sensitive schemes) and checks whether the service follows the supplied redirect or attempts to reach internal destinations. When JWT tokens are involved, the scan also verifies whether tokens are forwarded to untrusted hosts, which would constitute a high-severity finding under the BFLA/Privilege Escalation and SSRF checks.

Remediation guidance centers on two controls: strict URL allowlisting and separation of trust boundaries. Do not forward user-supplied URLs to internal services, and never propagate JWTs to destinations that are not explicitly trusted. In cases where outbound calls are required, use a dedicated service account with minimal permissions and enforce network-level restrictions (for example, egress rules that block private IP ranges).

Jwt Tokens-Specific Remediation in Actix — concrete code fixes

To mitigate SSRF in Actix when JWT tokens are used, ensure that any outbound HTTP client is configured with strict destination validation and does not automatically forward incoming Authorization headers. Below are two approaches: a vulnerable pattern and a secure pattern with code examples.

Vulnerable pattern (for illustration)

use actix_web::{web, HttpResponse, HttpRequest};
use reqwest::Client;
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};

async fn proxy_endpoint(
    req: HttpRequest,
    body: web::Json,
) -> HttpResponse {
    // Extract token from incoming request
    let auth_header = req.headers().get("Authorization");
    let token = match auth_header {
        Some(h) => h.to_str().unwrap_or("").strip_prefix("Bearer ").unwrap_or(""),
        None => return HttpResponse::Unauthorized().finish(),
    };

    // Decode token for claims (validation skipped for brevity)
    let _claims = decode::(
        token,
        &DecodingKey::from_secret("secret".as_ref()),
        &Validation::new(Algorithm::HS256),
    ).map_err(|_| HttpResponse::Unauthorized().finish())?;

    // Build client and forward to user-supplied URL — SSRF risk
    let client = Client::new();
    let target = body.get("target_url").and_then(|v| v.as_str()).unwrap_or("");
    let response = client.get(target)
        .bearer_auth(token)
        .send()
        .await;

    match response {
        Ok(resp) => HttpResponse::Ok().body(resp.text().await.unwrap_or_default()),
        Err(_) => HttpResponse::BadGateway().finish(),
    }
}

Secure remediation with allowlist and header separation

use actix_web::{web, HttpResponse, HttpRequest};
use reqwest::Client;
use url::Url;

async fn secure_proxy_endpoint(
    body: web::Json,
) -> HttpResponse {
    let target = match body.get("target_url").and_then(|v| v.as_str()) {
        Some(u) => u,
        None => return HttpResponse::BadRequest().body("target_url is required"),
    };

    // Strict allowlist: only specific hosts and HTTPS
    let parsed = match Url::parse(target) {
        Ok(u) => u,
        Err(_) => return HttpResponse::BadRequest().body("invalid URL"),
    };
    if parsed.scheme() != "https" {
        return HttpResponse::BadRequest().body("only HTTPS allowed");
    }
    let host = match parsed.host_str() {
        Some(h) => h,
        None => return HttpResponse::BadRequest().body("missing host"),
    };
    if !["api.trusted.com", "internal.service.corp"].contains(&host) {
        return HttpResponse::BadRequest().body("host not allowed");
    }

    // Build client without injecting the incoming Authorization header
    let client = Client::new();
    let response = match client.get(parsed).send().await {
        Ok(r) => r,
        Err(_) => return HttpResponse::BadGateway().body("request failed"),
    };

    // Optionally map selected response headers/body
    HttpResponse::Ok().body(response.text().await.unwrap_or_default())
}

Key points in the secure example:

  • The incoming JWT is not forwarded; authentication for the outbound call is handled separately (e.g., via a static key or service-specific credentials scoped to the allowed host).
  • URL parsing and an explicit allowlist prevent redirection to internal or cloud metadata endpoints.
  • The Actix handler remains focused on the intended business flow, avoiding automatic propagation of untrusted inputs.

middleBrick scans can validate that your OpenAPI spec and runtime behavior align with these practices by flagging endpoints that forward user-controlled URLs with bearer authorization and by checking for missing host allowlists.

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 via JWT tokens expose cloud instance metadata in Actix services?
Yes. If an Actix endpoint forwards user-supplied URLs and includes a JWT bearer token, an attacker can direct the request to cloud metadata endpoints (e.g., 169.254.169.254) and exfiltrate sensitive instance or role information.
Does middleBrick detect SSRF paths that involve forwarded JWT tokens?
Yes. middleBrick’s SSRF and BFLA/Privilege Escalation checks correlate OpenAPI definitions with runtime probes to identify whether tokens are forwarded to untrusted destinations, and it reports findings with specific remediation steps.