MCPcopy
hub / github.com/garrytan/gstack / resolvesToBlockedIp

Function resolvesToBlockedIp

browse/src/url-validation.ts:84–110  ·  view source on GitHub ↗

* Resolve a hostname to its IP addresses and check if any resolve to blocked metadata IPs. * Mitigates DNS rebinding: even if the hostname looks safe, the resolved IP might not be. * * Checks both A (IPv4) and AAAA (IPv6) records — an attacker can use AAAA-only DNS to * bypass IPv4-only checks.

(hostname: string)

Source from the content-addressed store, hash-verified

82 * (e.g. no AAAA records exist) is not treated as a rebinding risk.
83 */
84async function resolvesToBlockedIp(hostname: string): Promise<boolean> {
85 try {
86 const dns = await import('node:dns');
87 const { resolve4, resolve6 } = dns.promises;
88
89 // Check IPv4 A records
90 const v4Check = resolve4(hostname).then(
91 (addresses) => addresses.some(addr => BLOCKED_METADATA_HOSTS.has(addr)),
92 () => false, // ENODATA / ENOTFOUND — no A records, not a risk
93 );
94
95 // Check IPv6 AAAA records — the gap that issue #668 identified
96 const v6Check = resolve6(hostname).then(
97 (addresses) => addresses.some(addr => {
98 const normalized = addr.toLowerCase();
99 return BLOCKED_METADATA_HOSTS.has(normalized) || isBlockedIpv6(normalized);
100 }),
101 () => false, // ENODATA / ENOTFOUND — no AAAA records, not a risk
102 );
103
104 const [v4Blocked, v6Blocked] = await Promise.all([v4Check, v6Check]);
105 return v4Blocked || v6Blocked;
106 } catch {
107 // Unexpected error — fail open (don't block navigation on DNS infrastructure failure)
108 return false;
109 }
110}
111
112/**
113 * Normalize non-standard file:// URLs into absolute form before the WHATWG URL parser

Callers 1

validateNavigationUrlFunction · 0.85

Calls 1

isBlockedIpv6Function · 0.85

Tested by

no test coverage detected