User-supplied URL passed to fetch() without validation — attackers bypass DNS blocks via IP notation tricks.
Server-Side Request Forgery happens when a user-supplied URL is passed to `fetch()` or `http.request()` without proper validation. If the IP address is parsed incorrectly, attackers bypass DNS-based blocks using octal/hex IPv4 notation, IPv6 variants, or URL redirects. The `ip` npm package’s `isPublic()` had a bug where `127.1` (== 127.0.0.1) was classified as public.
// VULNERABLE — no SSRF protection
app.get('/fetch', async (req, res) => {
const url = req.query.url;
const response = await fetch(url); // attacker: ?url=http://127.1:8080/admin
res.json(await response.json());
});
// FIXED — explicit allowlist + URL parsing
const ALLOWED_HOSTS = ['api.example.com', 'cdn.example.com'];
app.get('/fetch', async (req, res) => {
const url = new URL(req.query.url);
if (!ALLOWED_HOSTS.includes(url.hostname)) {
return res.status(403).json({ error: 'Host not allowed' });
}
const response = await fetch(url.href);
res.json(await response.json());
});
pool.query(`SELECT * FROM users WHERE id = ${req.params.id}`)