Fix SSRF (Server Side Request Forgery) in Actix Web
SSRF in Actix Web occurs when an application accepts a user-controlled URL and fetches it using an HTTP client like `awc` or `reqwest` without proper validation. This allows attackers to scan internal networks, access cloud metadata services (e.g., 169.254.169.254), or bypass firewalls by leveraging the server's trusted identity.
The Vulnerable Pattern
use actix_web::{get, web, HttpResponse, Responder}; use awc::Client; use serde::Deserialize;#[derive(Deserialize)] struct Target { url: String }
#[get(“/proxy”)] async fn proxy(query: web::Query) -> impl Responder { let client = Client::default(); // VULNERABLE: Direct use of user-supplied URL allows access to localhost or internal IPs match client.get(&query.url).send().await { Ok(mut res) => HttpResponse::Ok().body(res.body().await.unwrap()), Err(_) => HttpResponse::InternalServerError().finish(), } }
The Secure Implementation
The secure implementation applies three critical layers of defense. First, it uses the `url` crate to parse the input, ensuring it is a valid URI. Second, it enforces a protocol allowlist (HTTPS only) to prevent usage of `file://`, `gopher://`, or `ftp://` schemes. Third, it implements a strict domain allowlist. For high-security environments, you should also perform DNS resolution and verify that the resulting IP address does not fall within private or reserved CIDR blocks (e.g., 10.0.0.0/8, 127.0.0.1) to prevent DNS rebinding attacks and internal network pivoting.
use actix_web::{get, web, HttpResponse, Responder}; use url::Url; use std::collections::HashSet;#[get(“/proxy”)] async fn secure_proxy(query: web::Query
) -> impl Responder { let parsed_url = match Url::parse(&query.url) { Ok(u) => u, Err(_) => return HttpResponse::BadRequest().body(“Invalid URL”), }; // 1. Protocol Enforcement if parsed_url.scheme() != "https" { return HttpResponse::Forbidden().body("Only HTTPS allowed"); } // 2. Domain Allowlisting let mut allowed_hosts = HashSet::new(); allowed_hosts.insert("api.trusted-service.com"); let host = parsed_url.host_str().unwrap_or(""); if !allowed_hosts.contains(host) { return HttpResponse::Forbidden().body("Disallowed target host"); } // 3. Request Execution let client = awc::Client::default(); match client.get(parsed_url.as_str()).send().await { Ok(mut res) => HttpResponse::Ok().body(res.body().await.unwrap()), Err(_) => HttpResponse::BadGateway().finish(), }
}
Protect your Actix Web API
Don't rely on manual checks. GuardAPI's Gemini 3 Pro engine detects SSRF (Server Side Request Forgery) and logic flaws in seconds.
Run Automated AuditVerified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.