Server-Side Request Forgery (SSRF)
What Is This Vulnerability?
SSRF occurs when an application fetches a remote resource using a URL supplied by the user without validating the destination. Attackers can make the server send requests to internal services, cloud metadata endpoints, or other resources that are not directly accessible from the internet, potentially leaking sensitive data or escalating access.
Why It Happens
Applications commonly need to fetch external resources for features like URL previews, webhook delivery, or file imports. When the target URL is taken directly from user input, there is no guarantee it points to an external host. Internal network addresses, localhost, and cloud metadata IPs (169.254.169.254) become reachable.
Example Code
app.post("/fetch-url", async (req, res) => {
const { url } = req.body;
const response = await fetch(url);
const data = await response.text();
res.send(data);
});import { URL } from "url";
const BLOCKED_HOSTS = ["localhost", "127.0.0.1", "169.254.169.254", "0.0.0.0"];
app.post("/fetch-url", async (req, res) => {
const { url } = req.body;
const parsed = new URL(url);
if (BLOCKED_HOSTS.includes(parsed.hostname) || parsed.hostname.endsWith(".internal")) {
return res.status(400).send("Blocked host");
}
if (parsed.protocol !== "https:") {
return res.status(400).send("Only HTTPS allowed");
}
const response = await fetch(url);
const data = await response.text();
res.send(data);
});How Hackers Exploit It
Attackers supply URLs like http://169.254.169.254/latest/meta-data/iam/security-credentials/ to steal cloud IAM credentials, or http://localhost:6379/ to interact with an internal Redis instance. DNS rebinding attacks can bypass hostname checks by resolving to an internal IP after validation. The server acts as a proxy, giving the attacker access to the internal network.
How to Fix It
Validate and parse URLs before fetching. Maintain an allowlist of permitted domains when possible, or at minimum block private IP ranges, localhost, and cloud metadata endpoints. Resolve the hostname to an IP address and verify it is not in a private range before making the request. Enforce HTTPS-only and set network-level firewall rules to restrict outbound traffic from the application.