the caller-controlled URL to validate.
the parsed URL, ready to fetch.
when the URL is malformed, uses an unsupported scheme, fails to resolve, or resolves to any private or reserved address.
// e.g. checking a batch of links before probing them
for (const link of links) {
try {
await AssertPublicUrl(link.url);
link.valid = true;
} catch (error) {
if (!(error instanceof SSRFError)) throw error;
link.valid = false; // one bad URL must not fail the whole batch
link.reason = error.message;
}
}
Validates a URL for SSRF safety, resolving its hostname to check where it actually points.
Four checks, in order — any one of them rejects:
httporhttps. This blocksfile://,gopher://,ftp://, and the rest, which are otherwise a rich source of SSRF primitives.fetch.[::1]— are checked the same way.Checking every address, rather than the first, is what closes the multi-record bypass: an attacker controlling DNS can publish one public A record alongside
127.0.0.1and rely on the resolver picking whichever it likes.IMPORTANT — validation alone is not protection. There is an unavoidable gap between this check and the connection that follows, during which DNS can change (a classic rebinding race). Prefer SafeFetch, which re-validates every redirect hop; see the package README's "What this does not protect against" section for the residual risk and how to close it.