Problem
Features such as webhooks, URL previews and imports let users supply URLs, and string-built SQL or shell commands let input become code. Attackers use these to reach cloud metadata endpoints, internal services, or the database itself.
Also known as: input-sanitization-boundary, egress-allow-listing, parameterized-queries
Design request handling so untrusted input can neither choose where the server connects nor change the meaning of a command or query.
Features such as webhooks, URL previews and imports let users supply URLs, and string-built SQL or shell commands let input become code. Attackers use these to reach cloud metadata endpoints, internal services, or the database itself.
Server-side request forgery turns your server into a proxy into networks the attacker cannot reach. Injection turns data into instructions. Both stem from letting untrusted input cross a trust boundary unchecked, and both are fixed by structure rather than filtering.
Make the safe path the easy one by providing a single shared HTTP client for user-supplied URLs and a data access layer that only accepts parameters. Add static analysis rules that flag raw string queries and unvetted outbound requests, and include these vulnerability classes in routine penetration tests.
fetch(userUrl):
u = parse(userUrl); require scheme == https, port in 443
require host in allowList OR public-only
ip = resolve(u.host)
reject if ip in 10/8, 172.16/12, 192.168/16, 127/8, 169.254/16, ::1, fc00::/7
connect to ip with Host header = u.host # no second DNS lookup
follow redirects manually, repeat checks, max 3 hops
limit size and time; run in sandbox with egress proxy
query: db.execute("SELECT * FROM t WHERE id = ?", [id]) # never concatenate
Low to medium — egress proxy
Low to medium
Medium
DNS rebinding passes validation then connects to an internal address
Redirect to an internal URL after a safe first hop
One raw query concatenation reopens SQL injection