render_unauthorized built the post-login return URL directly from the attacker-influenceable X-Forwarded-Host / X-Forwarded-Uri headers, stored it in the session, and reflected it into the signin `rd`. After authentication that URL is followed with allow_other_host, so a spoofed host was an open redirect. Now the forwarded URL is only honoured if it resolves to a known, active forward-auth application (via validate_redirect_url); otherwise it falls back to a validated `rd` or the IdP's base URL. Once render_unauthorized only ever stores a validated value, the sessions_controller "supplement, don't replace" behaviour is safe, so no change is needed there. Two integration tests were asserting the old behaviour by reflecting unregistered hosts (grafana.example.com, app.example.com); they now register those domains as forward-auth apps so they exercise the real feature. Adds a regression test that a spoofed X-Forwarded-Host is neither stored nor reflected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9.5 KiB
9.5 KiB