Fix SSRF (Server Side Request Forgery) in Tide
SSRF in Tide applications typically manifests when user-controlled input is passed directly to an asynchronous HTTP client like 'surf' or 'reqwest' without strict validation. This allows attackers to coerce the server into making requests to internal metadata services (IMDS), loopback interfaces, or private network segments. To kill SSRF, you must move from a blacklist approach to a strict allowlist and validate the resolved IP addresses.
The Vulnerable Pattern
use tide::Request;async fn proxy_handler(req: Request<()>) -> tide::Result { let target_url: String = req.query()?; // VULNERABLE: Directly fetching a user-provided URL let mut res = surf::get(&target_url).await?; let body = res.body_string().await?; Ok(body.into()) }
#[async_std::main] async fn main() -> tide::Result<()> { let mut app = tide::new(); app.at(“/fetch”).get(proxy_handler); app.listen(“127.0.0.1:8080”).await?; Ok(()) }
The Secure Implementation
The fix involves three layers of defense. First, we use the 'url' crate to parse the input, ensuring it is a valid URI structure. Second, we enforce the HTTPS scheme to prevent protocol smuggling (e.g., file:// or gopher://). Third, we implement a strict domain allowlist. In high-security environments, you should also perform DNS resolution and verify that the resulting IP address does not fall within RFC1918 (private) or loopback ranges to prevent DNS rebinding attacks.
use tide::{Request, Response, StatusCode}; use url::Url; use std::collections::HashSet;async fn secure_proxy_handler(req: Request<()>) -> tide::Result { let target_param: String = req.query()?; let url = Url::parse(&target_param).map_err(|_| tide::Error::from_str(400, “Invalid URL”))?;
// 1. Protocol Enforcement if url.scheme() != "https" { return Ok(Response::new(StatusCode::BadRequest).set_body("Only HTTPS allowed")); } // 2. Domain Allowlist let allowed_domains: HashSet<&str> = ["api.trusted-partner.com", "static.example.com"].iter().cloned().collect(); let host = url.host_str().ok_or_else(|| tide::Error::from_str(400, "Missing host"))?; if !allowed_domains.contains(host) { return Ok(Response::new(StatusCode::Forbidden).set_body("Domain not authorized")); } // 3. Perform the request after validation let mut res = surf::get(url).await?; Ok(res.into())
}
Your Tide API
might be exposed to SSRF (Server Side Request Forgery)
74% of Tide apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified 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.