is-private-host
Version:
Check if a hostname or URL resolves to a private IP address
69 lines (68 loc) • 2.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: !0 });
var promises = require("node:dns/promises"), ipaddr_js = require("ipaddr.js");
const PRIVATE_IPV4_RANGES = [
// Unspecified
"0.0.0.0/8",
// Private Class A
"10.0.0.0/8",
// CGNAT (Optional)
"100.64.0.0/10",
// Loopback
"127.0.0.0/8",
// Link-local
"169.254.0.0/16",
// Private Class B
"172.16.0.0/12",
// Private Class C
"192.168.0.0/16"
], PRIVATE_IPV6_RANGES = [
// Unspecified
"::/128",
// Loopback
"::1/128",
// IPv4-Mapped IPv6
"::ffff:0:0/96",
// NAT64
"64:ff9b::/96",
// Unique Local Addresses (ULA)
"fc00::/7",
// Link-local
"fe80::/10"
], privateRanges = {
ipv4: PRIVATE_IPV4_RANGES,
ipv6: PRIVATE_IPV6_RANGES
};
function isPrivateIP(ipAddress) {
try {
const parsedIP = ipaddr_js.parse(ipAddress);
return (parsedIP.kind() === "ipv4" ? privateRanges.ipv4 : privateRanges.ipv6).some((range) => {
const subnet = ipaddr_js.parseCIDR(range);
return parsedIP.match(subnet);
});
} catch {
throw new Error(`Invalid IP address "${ipAddress}"`);
}
}
async function isPrivateHost(hostname, options) {
try {
const addresses = await promises.lookup(hostname, {
// Check both IPv4 and IPv6 records since we don't know which one will be used in the end
all: !0
}), isPrivate = addresses.some(({ address }) => isPrivateIP(address));
return options && options.withResolveInfo ? { isPrivate, addresses } : isPrivate;
} catch (error) {
throw new Error(
`Error resolving hostname "${hostname}": ${error instanceof Error ? error.message : error}`,
{ cause: error }
);
}
}
async function isPrivateUrl(url, options) {
const parsedUrl = new URL(url), { isPrivate, addresses } = await isPrivateHost(parsedUrl.hostname, { withResolveInfo: !0 }), resolveInfo = { isPrivate, parsedUrl, addresses };
return options && options.withResolveInfo ? resolveInfo : isPrivate;
}
exports.isPrivateHost = isPrivateHost;
exports.isPrivateIP = isPrivateIP;
exports.isPrivateUrl = isPrivateUrl;
//# sourceMappingURL=index.cjs.map