var dns = require('dns').promises; var net = require('net'); function isPrivateIp(ip) { if (!ip) return true; if (net.isIPv4(ip)) { var p = ip.split('.').map(Number); if (p[0] === 10 || p[0] === 127 || p[0] === 0) return true; if (p[0] === 100 && p[1] >= 64 && p[1] <= 127) return true; if (p[0] === 169 && p[1] === 254) return true; if (p[0] === 172 && p[1] >= 16 && p[1] <= 31) return true; if (p[0] === 192 && p[1] === 168) return true; if (p[0] >= 224) return true; return false; } if (net.isIPv6(ip)) { var low = ip.toLowerCase(); if (low === '::1' || low === '::') return true; if (low.startsWith('fe80:') || low.startsWith('fc') || low.startsWith('fd')) return true; return false; } return true; } async function assertSafeHttpsUrl(urlStr, label) { var u; try { u = new URL(urlStr); } catch (e) { throw new Error((label || 'URL') + ' is invalid'); } if (u.protocol !== 'https:') throw new Error((label || 'URL') + ' must use https://'); if (u.username || u.password) throw new Error((label || 'URL') + ' must not include credentials'); var addrs = await dns.lookup(u.hostname, { all: true }); if (!addrs.length) throw new Error((label || 'URL') + ' did not resolve'); for (var i = 0; i < addrs.length; i++) { if (isPrivateIp(addrs[i].address)) throw new Error((label || 'URL') + ' resolves to a private IP'); } return u; } module.exports = { assertSafeHttpsUrl: assertSafeHttpsUrl, isPrivateIp: isPrivateIp };