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.
  • Safety - what Vulkro does and does not access on your machine.

References


This page is generated by vulkro rules export <out-dir> from the catalog in src/rule_docs.rs. Edits made by hand are overwritten on the next regeneration.