Add CSRF state cookie protection to CellsAwareOpenidConnect
Summary
In the Cells architecture, the OAuth callback may arrive at a different cell than the one that initiated the request. Session-based CSRF state is therefore unreliable. This MR adds CSRF protection via a short-lived omniauth_oauth_state cookie to CellsAwareOpenidConnect.
During request_phase, the cookie is set with the OmniAuth state value. During callback_phase, the cookie is validated against the state URL parameter using Rack::Utils.secure_compare. On success the cookie is cleared after the app response is built (via a deferred @pending_cookie_clear flag in call_app!); on failure fail!(:csrf_detected, ...) is called immediately and the cookie is cleared from the error response.
Cookie attributes
Set-Cookie: omniauth_oauth_state=<state>; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600The Max-Age of 600 seconds matches the IAM Auth Service parked-session TTL.
References
- Closes #592379 (closed)
- Parent epic: gitlab-org#21221
- Depends on cross-cell session management: #591999 (closed)