Closes the open-redirect risk surfaced by the v0.3.x security audit:
the OIDC callback handler was using oidc_config.post_login_redirect
verbatim as the redirect base on both error and success paths. An
attacker with admin-key compromise (or a misconfigured operator) could
set that field to an external domain and turn /api/auth/oidc/callback
into a phishing redirector ('dialectic login failed → re-enter
password at evil.com/login').
Fix:
- New AuthHandler.safeRedirectBase(raw) validator:
* empty → '/'
* relative path starting with '/' (but not '//') → keep as-is
* absolute URL whose host is in the allow-list → keep as-is
* everything else → '/'
- allow-list sourced from cfg.CORSAllowOrigins (the same set we
already trust for browser CORS), threaded through NewAuthHandler.
- Applied on BOTH the error branch and success branch of Callback.
Also: drop redundant newline on cmd/dialectic-cli usage Fprintln so
go test ./... passes.
No behavior change for happy path: prod's PostLoginRedirect is
'https://dialectic.hangman-lab.top/oidc/callback', which matches the
CORS allow-list ('https://dialectic.hangman-lab.top'), so the
validator returns it unmodified.