From 44cc4b367e040c283bb4dd09b45cab13b1d4aaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Cohen=20Arazi?= Date: Wed, 19 Aug 2026 09:31:38 -0300 Subject: [PATCH] Bug 42719: [26.05.x] Handle missing CGISESSID in OAuth login (IdP-initiated flow) When a user initiates login from the IdP (e.g. Okta app tile), they hit the OAuth endpoint without an existing session cookie. The code crashed calling ->value on an undefined cookie object. This patch: - Removes the premature 'No user session found' guard that blocked IdP-initiated flows entirely - Creates a session on-the-fly for the initial request when no cookie exists (IdP-initiated flow) - On callback, redirects with wrong_csrf_token error instead of crashing when the cookie is missing CSRF protection is preserved: the state token is bound to the session created in the initial request, and the browser returns the cookie on callback for validation. Signed-off-by: Tomas Cohen Arazi (cherry picked from commit cd02922675f42f1c404acaa274d14fd155778941) Signed-off-by: Lucas Gass --- Koha/REST/V1/OAuth/Client.pm | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Koha/REST/V1/OAuth/Client.pm b/Koha/REST/V1/OAuth/Client.pm index 3b5ea677d3..9699a06478 100644 --- a/Koha/REST/V1/OAuth/Client.pm +++ b/Koha/REST/V1/OAuth/Client.pm @@ -66,10 +66,11 @@ sub login { } my $current_session; + my $session_id; my $current_session_cookie = $c->req->cookie('CGISESSID'); if ($current_session_cookie) { - my $current_session_id = $current_session_cookie->value; - $current_session = Koha::Session->get_session( { sessionID => $current_session_id } ); + $session_id = $current_session_cookie->value; + $current_session = Koha::Session->get_session( { sessionID => $session_id } ); } unless ( $provider_config && $provider_config->{authorize_url} ) { @@ -91,10 +92,15 @@ sub login { if ($is_callback) { # callback, check CSRF token + unless ($session_id) { + my $error = "wrong_csrf_token"; + return $c->redirect_to( $uri . "?auth_error=$error" ); + } + unless ( Koha::Token->new->check_csrf( { - session_id => $c->req->cookie('CGISESSID')->value, + session_id => $session_id, token => $c->param('state'), } ) @@ -105,8 +111,14 @@ sub login { } } else { - # initial request, generate CSRF token - $state = Koha::Token->new->generate_csrf( { session_id => $c->req->cookie('CGISESSID')->value } ); + # initial request — create session if needed (IdP-initiated flow) + unless ($session_id) { + $current_session = Koha::Session->get_session( {} ); + $session_id = $current_session->id; + $c->cookie( CGISESSID => $session_id, { path => '/' } ); + } + + $state = Koha::Token->new->generate_csrf( { session_id => $session_id } ); Koha::Auth::Identity::Referer->store_referer( {