/** * Optional strict DNS-style host allowlist for HTTP clients (`BARE_OS_DNS_ALLOWLIST`). * Comma/whitespace-separated hostnames; `*.example.com` suffix wildcard when entry starts with `*.`. */ /** * @param {string} host * @param {string[]} allow */ function hostMatchesAllowlist(host, allow) { const h = String(host) .toLowerCase() .replace(/\.$/, '') for (const raw of allow) { const a = String(raw) .toLowerCase() .replace(/\.$/, '') if (!a) continue if (a.startsWith('*.')) { const root = a.slice(2) if (!root) continue if (h === root) return true if (h.endsWith('.' + root)) return true continue } if (h === a) return true } return false } /** * @param {Record} env * @returns {string[] | null} null = policy disabled */ export function parseDnsAllowlistFromEnv(env) { const raw = env && env.BARE_OS_DNS_ALLOWLIST if (raw == null || raw === '' || raw === '0' || raw === 'false') return null const list = String(raw) .split(/[\s,]+/) .map((s) => s.trim()) .filter(Boolean) return list.length ? list : null } /** * @param {string} urlString * @param {Record} env */ export function assertFetchUrlHostAllowedByDnsPolicy(urlString, env) { const allow = parseDnsAllowlistFromEnv(env) if (!allow) return let u try { u = new URL(urlString) } catch { return } if (u.protocol !== 'http:' && u.protocol !== 'https:') return const host = u.hostname if (!host) return if (hostMatchesAllowlist(host, allow)) return throw new Error( `BARE_OS_DNS_ALLOWLIST: host not allowed: ${host} (url ${urlString.slice(0, 120)})` ) }