Ssrf Blind in Actix (Rust)
Ssrf Blind in Actix with Rust — how this specific combination creates or exposes the vulnerability
Server-Side Request Forgery (SSRF) in Actix web applications written in Rust typically arises when an application accepts a URL from an untrusted source and uses it to initiate an outbound HTTP request without adequate validation or network scoping. In Rust, this often involves using crates such as reqwest or the Actix ecosystem’s HTTP client facilities to perform the external call. Because Actix is asynchronous and encourages composable service builders, a developer may compose a handler that forwards or fetches resources based on user input. If the input is used directly to construct the request target, an attacker can supply internal addresses, cloud metadata endpoints (e.g., http://169.254.169.254), or other restricted network destinations that the server-side process can reach. This blind SSRF scenario occurs when the application does not leak the response content directly but can influence whether and how a remote resource is accessed, allowing enumeration of internal services, port reachability, or exploitation of vulnerable internal endpoints.
In an Actix service, a typical handler might accept a JSON payload with a target URL and then use reqwest::Client to perform the request. Without strict allowlisting of hosts and ports, and without disabling unwanted features such as redirects or proxy inheritance, the server can be tricked into making requests to internal or otherwise unintended endpoints. Because Rust’s type system and ownership model do not inherently prevent network calls to arbitrary addresses, the developer must explicitly enforce network boundaries. The combination of Actix’s routing and handler flexibility with Rust’s ecosystem libraries can inadvertently expose a blind SSRF if input validation, network scoping, and egress controls are omitted. Common triggers include accepting raw strings for hostnames or paths, failing to reject private IP ranges, and permitting file:// or gopher:// schemes that can lead to unauthorized local file reads or internal protocol interactions.
An attacker may exploit blind SSRF to probe internal infrastructure, reach management interfaces not exposed to the public internet, or trigger interactions with legacy protocols that the Rust process can access. Even when responses are not returned to the client, side effects such as TCP connection attempts, DNS resolutions, or interactions with internal services can be observed through timing or network logs. This makes SSRF a precursor to further compromise, especially in containerized or cloud environments where metadata services are reachable from workloads. Mitigating this in Actix with Rust requires explicit validation of the target host, rejection of private and reserved IP ranges, restriction of allowed ports and schemes, and hardening of the HTTP client to prevent unintended routing or credential leakage.
Rust-Specific Remediation in Actix — concrete code fixes
To remediate SSRF in Actix applications written in Rust, validate and sanitize all user-controlled inputs used to form request targets. Prefer allowlisting known, safe hosts and paths, and reject private IP ranges, localhost references, and dangerous URL schemes. Use Rust crates that support URL parsing with strict host checks, and configure the HTTP client to prevent transparent redirects and to restrict the set of permitted ports. Below are concrete, idiomatic examples of secure Actix handlers in Rust.
use actix_web::{web, HttpResponse, Result};
use reqwest::Client;
use url::Url;
/// Validate that the target URL is safe: must be HTTPS, host must be in allowlist,
/// no private IPs, no dangerous schemes, and no redirects.
fn is_safe_target(input: &str, allowed_hosts: &[&str]) -> bool {
let parsed = match Url::parse(input) {
Ok(u) => u,
Err(_) => return false,
};
// Only allow https to reduce risk
if parsed.scheme() != "https" {
return false;
}
let host = match parsed.host_str() {
Some(h) => h,
None => return false,
};
// Explicit allowlist check
if !allowed_hosts.contains(&host) {
return false;
}
// Reject IP-based URLs to avoid bypass via host header or encoded IP
if parsed.host().map_or(false, |h| h.is_ip()) {
return false;
}
// Prevent common dangerous schemes
matches!(parsed.scheme(), "https" | "wss")
}
/// Secure Actix handler using a strict allowlist and a hardened reqwest client.
async fn fetch_external(
payload: web::Json,
) -> Result {
let target = match payload.get("url").and_then(|v| v.as_str()) {
Some(t) => t,
None => return Ok(HttpResponse::BadRequest().body("Missing url")),
};
let allowed_hosts = &["api.example.com", "cdn.example.com"];
if !is_safe_target(target, allowed_hosts) {
return Ok(HttpResponse::Forbidden().body("Target not allowed"));
}
// Build a client that does not follow redirects and has a short timeout.
let client = Client::builder()
.redirect(reqwest::redirect::Policy::none())
.timeout(std::time::Duration::from_secs(5))
.build()
.map_err(|e| actix_web::error::ErrorInternalServerError(e.to_string()))?;
let response = client
.get(target)
.send()
.await
.map_err(|e| actix_web::error::ErrorBadGateway(e.to_string()))?;
let body = response
.text()n .await
.map_err(|e| actix_web::error::ErrorBadGateway(e.to_string()))?;
Ok(HttpResponse::Ok().body(body))
}
In this example, is_safe_target enforces an allowlist, rejects non-HTTPS schemes, and blocks IP-based hosts to prevent bypass via encoded IPs or host headers. The Actix handler uses a reqwest::Client configured with no redirect policy and a timeout to limit exposure. For broader protection in your Actix service, consider factoring the validation into a reusable extractor or middleware so that all endpoints that perform outbound calls are consistently guarded.
Additionally, prefer configuration-driven allowlists over hardcoding when possible, and ensure that the runtime environment does not inadvertently inherit proxy settings or default routes that could reach unexpected internal addresses. Regular scanning with a tool like middleBrick can help identify lingering SSRF risks in your Actix services by correlating OpenAPI specifications with runtime behavior, providing prioritized findings and remediation guidance that maps to standards such as OWASP API Top 10.