Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Prevent SSRF when fetching user-supplied URLs
When the backend fetches a URL from client input (webhooks, previews, imports), validate with allowlists and block internal networks.
Bad example
| 1 | app.post('/preview', async (req, res) => { |
| 2 | // BAD: blindly fetches user-supplied URL |
| 3 | const r = await fetch(req.body.url); |
| 4 | const html = await r.text(); |
| 5 | res.json({ html }); |
| 6 | }); |
Explanation (EN)
Blindly fetching client-supplied URLs enables SSRF (internal port scanning, metadata theft like 169.254.169.254, proxying).
Objašnjenje (HR)
Slijepo fetchanje URL-a iz inputa omogućuje SSRF (interno port skeniranje, krađu metadata credentiala poput 169.254.169.254, proxying).
Good example
| 1 | const ALLOWED_HOSTS = new Set(['example.com', 'images.examplecdn.com']); |
| 2 | const ALLOWED_PROTOCOLS = new Set(['https:']); |
| 3 |
|
| 4 | app.post('/preview', async (req, res) => { |
| 5 | const url = new URL(req.body.url); |
| 6 |
|
| 7 | if (!ALLOWED_PROTOCOLS.has(url.protocol)) { |
| 8 | return res.status(400).json({ message: 'Invalid URL protocol' }); |
| 9 | } |
| 10 |
|
| 11 | if (!ALLOWED_HOSTS.has(url.hostname)) { |
| 12 | return res.status(400).json({ message: 'Host not allowed' }); |
| 13 | } |
| 14 |
|
| 15 | // Ensure DNS resolves to public IPs only and block redirects |
| 16 | const response = await fetchWithSafeguards(url.toString(), { timeoutMs: 2000, followRedirects: false }); |
| 17 | const text = await response.text(); |
| 18 |
|
| 19 | // Do not return raw upstream responses if not required |
| 20 | res.json({ ok: true, title: extractTitle(text) }); |
| 21 | }); |
Explanation (EN)
Use allowlists for hosts/schemes/ports, block redirects, enforce timeouts, and prevent access to internal IP ranges. Return only the minimum derived data.
Objašnjenje (HR)
Koristi allowlist za host/shemu/port, blokiraj redirecte, uvedi timeoute i spriječi pristup internim IP rangeovima. Vrati samo minimum izvedenih podataka.
Notes (EN)
Also: use a well-tested URL parser, sanitize inputs, isolate fetchers in the network, and never allow metadata services or localhost. Consider denylisting RFC1918, link-local, loopback, and cluster ranges.
Bilješke (HR)
Također: koristi provjeren URL parser, sanitiziraj input, izoliraj fetchere u mreži i nikad ne dopuštaj metadata servise ili localhost. Razmisli o denylistanju RFC1918, link-local, loopback i cluster rangeova.