Skip to main content

API7:2023 Server-Side Request Forgery

User-controlled URLs are fetched by the server. The attacker steers requests at internal hosts (cloud metadata services, RFC1918 ranges), bypassing perimeter firewalls.

What Vulkro detects​

Vulkro tracks taint from request body / query / path into HTTP client calls (requests.get, axios, fetch, http.Client.Get, etc.) without intervening URL validation or allowlist check.

Non-compliant code (examples)​

Express - user-supplied URL fetched directly

app.post('/webhook/probe', async (req, res) => {
const r = await fetch(req.body.url); // attacker hits 169.254.169.254
res.send(await r.text());
});

Compliant code (examples)​

Express - allowlist host + reject private IPs

const ALLOWED_HOSTS = new Set(['api.partner.com']);
app.post('/webhook/probe', async (req, res) => {
const url = new URL(req.body.url);
if (!ALLOWED_HOSTS.has(url.hostname)) return res.status(400).end();
// also verify resolved IP is not in 10.0.0.0/8, 172.16/12, 192.168/16, 169.254/16, 127.0/8
const r = await fetch(url.href, { redirect: 'error' });
res.send(await r.text());
});

See also​

  • Confidence model - what High, Medium, and Low mean for findings in this category.
  • Privacy - what Vulkro does and does not access on your machine.

References​


This page is generated by vulkro rules export <out-dir> from Vulkro's built-in detector catalogue. Edits made by hand are overwritten on the next regeneration.