Harden forward-auth redirect and header handling
All checks were successful
publish-latest / docker (push) Successful in 22s

Tighten forward-auth return URL validation to reject unsafe host syntax,
including backslash-based browser/parser mismatches, and normalize
scheme/port matching so bare allowlist entries are HTTPS default-port
only. Support explicit scheme-qualified targets, including IPv6
host:port entries.

Always emit deterministic identity headers with empty values when
attributes are absent, zero unsafe header values, and clear stale
forward-auth return targets when OIDC or registration flows take
precedence.

Add regression coverage for wildcard redirect bypasses, scheme/port
handling, IPv6 allowlist entries, empty identity headers, unsafe header
values, and stale return-target cleanup. Update docs with proxy
header-stripping guidance and the new allowlist semantics.
This commit is contained in:
Johan Lundberg 2026-07-05 00:00:58 +02:00
parent 58da15c825
commit 6b6ff29b9a
5 changed files with 325 additions and 60 deletions

View file

@ -140,9 +140,16 @@ forward_auth_allowed_redirect_hosts = ["app.example.com", "*.apps.example.com"]
The endpoint uses `X-Forwarded-Proto`, `X-Forwarded-Host`, and
`X-Forwarded-Uri` (or `X-Original-Url`) to reconstruct the original request URL.
Only exact hosts, `host:port` entries, or explicit `*.example.com` wildcard
suffixes listed in `forward_auth_allowed_redirect_hosts` are accepted as return
targets.
Bare host patterns are HTTPS-only and match the default HTTPS port; `host:port`
patterns are also HTTPS-only unless you include an explicit scheme such as
`http://localhost:9000` for local cleartext deployments. Exact hosts,
`host:port` entries, scheme-qualified hosts, and explicit `*.example.com`
wildcard suffixes listed in `forward_auth_allowed_redirect_hosts` are accepted
as return targets.
Configure the reverse proxy to strip any inbound `Remote-*` and `X-Forwarded-*`
identity headers from client requests before applying the headers returned by
`/forward-auth`.
To use a config file at a different path: