Files
bare-operating-system/packages/bare-os-booter/lib/bare-os-dns-policy.js
T
2026-04-04 01:20:57 -04:00

66 lines
1.7 KiB
JavaScript

/**
* 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<string, string | undefined>} 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<string, string | undefined>} 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)})`
)
}