Fix ForwardAuth fail-open and consent CSRF bypass
Two HIGH-severity findings from the security review: - ForwardAuth: when no host header was present, /api/verify skipped the application lookup and group check entirely, returning 200 with identity headers (including all of the user's groups). This bypassed per-domain access control. Now fails closed with 403, and the unreachable DEFAULT_HEADERS fallback (the bypass path) is removed so headers are always scoped to a resolved, active application. - OIDC: the consent endpoint was in the verify_authenticity_token skip list, so a forged cross-site POST could silently grant OAuth scopes. Removed :consent from the skip list (the form already embeds the token). Adds regression tests for both: fail-closed with no identity headers when host is absent, and 422 on a tokenless consent POST. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,11 @@ class OidcController < ApplicationController
|
||||
# Discovery and JWKS endpoints are public
|
||||
# authorize is also unauthenticated to handle prompt=none and prompt=login specially
|
||||
allow_unauthenticated_access only: [:discovery, :jwks, :token, :revoke, :userinfo, :logout, :authorize]
|
||||
skip_before_action :verify_authenticity_token, only: [:token, :revoke, :userinfo, :logout, :authorize, :consent]
|
||||
# Machine-to-machine endpoints (token/revoke/userinfo) and pure redirect handlers
|
||||
# (logout/authorize) legitimately skip CSRF. The consent endpoint is browser-facing
|
||||
# and state-changing (it grants OAuth scopes), so it MUST keep CSRF protection — the
|
||||
# consent form already embeds the token via form_with.
|
||||
skip_before_action :verify_authenticity_token, only: [:token, :revoke, :userinfo, :logout, :authorize]
|
||||
|
||||
# RFC 6749 §4.1.2.1: client_id and redirect_uri must be validated *before* any
|
||||
# other error can be reported via redirect. Failures here render a plain page.
|
||||
|
||||
Reference in New Issue
Block a user