fix: CSRF check supports reverse proxy headers (#218) (#219)

Tests pass: 20/21 QA suite (1 known skip), all browser API sanity checks green, CSRF fix verified end-to-end.
This commit is contained in:
Nathan Esquenazi
2026-04-10 01:24:18 -07:00
committed by GitHub
parent e3c85624d9
commit e0a95193d8

View File

@@ -32,11 +32,20 @@ def _check_csrf(handler) -> bool:
if not origin and not referer:
return True # non-browser clients (curl, agent) have no Origin
target = origin or referer
# Allow same-origin: Origin must match Host
if host and target:
# Extract host:port from origin/referer
m = _re.match(r'^https?://([^/]+)', target)
if m and m.group(1) == host:
if not m:
return False
origin_host = m.group(1)
# Allow same-origin: check Host, X-Forwarded-Host (reverse proxy), and
# X-Real-Host against the origin. Reverse proxies (Caddy, nginx) set
# X-Forwarded-Host to the client's original Host header.
allowed_hosts = {h.strip() for h in [
host,
handler.headers.get('X-Forwarded-Host', ''),
handler.headers.get('X-Real-Host', ''),
] if h.strip()}
if origin_host in allowed_hosts:
return True
return False
from api.models import (