If your server fetches a URL that the user provides, an attacker can point it at your internal network or your cloud provider's metadata endpoint instead of an external site. That turns your server into a proxy for reaching things it should never expose. The fix is to validate the destination against an allowlist and block internal addresses.
Why it's a problem
Your server usually sits inside a trusted network, so a request it makes can reach internal services, admin panels, and the cloud metadata endpoint that hands out credentials. An attacker who controls the URL you fetch can read those responses or trigger internal actions, which is why SSRF is often a path to full compromise.
The pattern
// fetches whatever URL the user sends
app.post("/preview", async (req, res) => {
const r = await fetch(req.body.url);
res.send(await r.text());
});The fix
const ALLOWED_HOSTS = new Set(["images.example.com"]);
app.post("/preview", async (req, res) => {
const url = new URL(req.body.url);
// only https, only approved hosts, never internal addresses
if (url.protocol !== "https:" || !ALLOWED_HOSTS.has(url.hostname)) {
return res.sendStatus(400);
}
const r = await fetch(url);
res.send(await r.text());
});Why AI tools write this
Fetching a user-provided URL is the direct implementation of features like link previews, webhooks, and image imports, so it is a natural completion. It works against public URLs in testing, and the internal-network reach only becomes a weapon when an attacker supplies an internal address.
The quick fix
- Validate the URL against an allowlist of hosts you trust.
- Allow only https and block requests to private and link-local IP ranges and the cloud metadata endpoint.
- Do not follow redirects to unapproved hosts.
Common questions
What is the cloud metadata endpoint and why is it dangerous in SSRF?
AWS, GCP, and Azure expose an HTTP endpoint at 169.254.169.254 that returns credentials for the running instance. An SSRF attacker who points your server at that URL can retrieve cloud credentials.
Does blocking the cloud metadata IP cover all SSRF risk?
No. Internal network ranges (10.x, 192.168.x, 172.16-31.x, and loopback 127.0.0.1) should also be blocked, as should DNS rebinding, which can resolve a benign hostname to an internal address after your check.
Is SSRF only a problem for full fetch operations?
No. Any server-side operation that uses a user-supplied URL is at risk: webhooks, link preview generators, image importers, XML parsers with external entities, and PDF renderers.