rendergate-mainnet / url-policy.js
tantk's picture
initial deploy: hardened mainnet build
dcf8b6b verified
// Shared URL policy. Used both at request entry (server.js) and per-request
// inside the renderer (renderer.js) so redirects to private IPs are blocked.
const PRIVATE_HOSTNAMES = new Set([
"localhost",
"127.0.0.1",
"0.0.0.0",
"[::1]",
"::1",
]);
/**
* Returns true if `urlStr` is a public http(s) URL we're willing to fetch.
* Rejects: non-http(s) schemes, localhost, IPv6 literals, RFC1918 IPv4,
* link-local, and anything that fails to parse.
*/
export function isAllowedUrl(urlStr) {
let parsed;
try {
parsed = new URL(urlStr);
} catch {
return false;
}
if (!["http:", "https:"].includes(parsed.protocol)) return false;
const host = parsed.hostname;
if (PRIVATE_HOSTNAMES.has(host)) return false;
if (host.startsWith("[")) return false; // any IPv6 literal — overly cautious by design
if (host === "::1") return false;
// RFC1918 + link-local IPv4 ranges
const parts = host.split(".");
if (parts[0] === "10") return false;
if (parts[0] === "172" && +parts[1] >= 16 && +parts[1] <= 31) return false;
if (parts[0] === "192" && parts[1] === "168") return false;
if (parts[0] === "169" && parts[1] === "254") return false;
return true;
}