fix: accept proxied Host/PUBLIC_BASE_URL in checkOrigin

This commit is contained in:
portakal 2026-06-16 14:43:34 +03:00
commit de1282fcd6

View file

@ -59,6 +59,22 @@ export function requireAdmin(req, res, next) {
next(); next();
} }
// Set of hostnames a same-site request may originate from. Behind a reverse proxy the
// raw Host header may be the upstream (127.0.0.1:8077), so we also trust the canonical
// host from PUBLIC_BASE_URL and the X-Forwarded-Host the proxy sends.
function allowedHosts(req) {
const hosts = new Set();
if (req.get('host')) hosts.add(req.get('host'));
const xfh = req.get('x-forwarded-host');
if (xfh) xfh.split(',').forEach((h) => hosts.add(h.trim()));
try {
if (config.publicBaseUrl) hosts.add(new URL(config.publicBaseUrl).host);
} catch {
/* ignore malformed PUBLIC_BASE_URL */
}
return hosts;
}
// Lightweight CSRF defense: state-changing requests must originate same-host. // Lightweight CSRF defense: state-changing requests must originate same-host.
export function checkOrigin(req, res, next) { export function checkOrigin(req, res, next) {
if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) return next(); if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) return next();
@ -66,7 +82,7 @@ export function checkOrigin(req, res, next) {
if (origin) { if (origin) {
try { try {
const host = new URL(origin).host; const host = new URL(origin).host;
if (host === req.get('host')) return next(); if (allowedHosts(req).has(host)) return next();
} catch { } catch {
/* fall through */ /* fall through */
} }