diff --git a/server/src/agents/endpoint.ts b/server/src/agents/endpoint.ts index 1a7656b3..39c979d4 100644 --- a/server/src/agents/endpoint.ts +++ b/server/src/agents/endpoint.ts @@ -49,7 +49,7 @@ function namedAsAllowed( return false; } const hostname = url.hostname.toLowerCase().replace(/^\[|\]$/g, ""); - const host = url.host.toLowerCase().replace(/^\[/, "").replace(/\]/, ""); + const host = url.port ? `${hostname}:${url.port}` : hostname; return allowedHosts.has(host) || allowedHosts.has(hostname); } diff --git a/server/src/config.ts b/server/src/config.ts index 1c235f9c..09c92598 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -634,11 +634,25 @@ function agentEndpointAllowedHosts( `AGENT_ENDPOINT_ALLOWED_HOSTS entry "${entry}" must name one host. Patterns are not accepted: list each address instead.`, ); } - hosts.add(host.replace(/^\[/, "").replace(/\]$/, "")); + hosts.add(normalizeAllowedHost(host)); } return hosts; } +function normalizeAllowedHost(host: string): string { + // IPv6 is bracketed as [host] or [host]:port. Strip the brackets and keep the port. + if (host.startsWith("[")) { + const close = host.indexOf("]"); + if (close === -1) return host.replace(/^\[/, "").replace(/\]$/, ""); + const ipv6 = host.slice(1, close).toLowerCase(); + const rest = host.slice(close + 1); + if (!rest) return ipv6; + if (rest.startsWith(":")) return `${ipv6}${rest.toLowerCase()}`; + return `${ipv6}${rest.toLowerCase()}`; + } + return host; +} + function privateHostsAllowed(environment: Environment): boolean { if (optional(environment, "AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS") !== "true") { return false;