From f965db69f1b1aaa0afaf7a3a48723f7e87c5b32c Mon Sep 17 00:00:00 2001 From: David Cook Date: Fri, 30 Jun 2023 02:50:17 +0000 Subject: [PATCH] Bug 34163: Handle both anonymous userenv when generating CSRF tokens An anonymous session might have a userenv which is undef or which is a hashref of undef/empty values. This patch generates the "anonymous" prefix for undef/empty 'id' values, which prevents CSRF errors when logging in via OAuth2/OIDC following a Koha logout. Test plan: Before applying patch: 1. Go to https://wiki.koha-community.org/wiki/Testing_SSO 2. Set up OpenID Connect realm, user, client, and Koha integration to Keycloak for koha-testing-docker as noted in the wiki 3. Go to http://localhost:8080/cgi-bin/koha/opac-main.pl?logout.x=1 4. Click on OIDC "Log in with XXXX" button and log into IDP 5. Note that you're not logged in and you instead see an error message like: "There was an error authenticating to external identity provider wrong_csrf_token" 6. Apply patch 7. Go to "Sessions" section of the test realm in Keycloak e.g. http://sso:8082/auth/admin/master/console/#/test/sessions 8. Click "Action" on the far right side of the screen 9. Choose "Sign out all active sessions" After applying patch: 10. koha-plack --restart kohadev 11. Go to http://localhost:8080/cgi-bin/koha/opac-main.pl?logout.x=1 12. Click on OIDC "Log in with XXXX" button and log into IDP 13. Note that you're logged in 14. prove t/Token.t 15. Note all tests pass Signed-off-by: Tomas Cohen Arazi --- Koha/Token.pm | 5 ++++- t/Token.t | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Koha/Token.pm b/Koha/Token.pm index b7cdd3ad96..c4d23aeada 100644 --- a/Koha/Token.pm +++ b/Koha/Token.pm @@ -215,7 +215,10 @@ sub decode_jwt { sub _add_default_csrf_params { my ( $params ) = @_; $params->{session_id} //= DEFA_SESSION_ID; - my $userenv = C4::Context->userenv // { id => DEFA_SESSION_USERID }; + my $userenv = C4::Context->userenv; + if ( ( !$userenv ) || !$userenv->{id} ) { + $userenv = { id => DEFA_SESSION_USERID }; + } $params->{id} //= Encode::encode( 'UTF-8', $userenv->{id} ); $params->{id} .= '_' . $params->{session_id}; diff --git a/t/Token.t b/t/Token.t index 2e38451c19..d34089a908 100755 --- a/t/Token.t +++ b/t/Token.t @@ -120,7 +120,7 @@ subtest 'JWT' => sub { }; subtest 'testing _add_default_csrf_params with/without userenv (bug 27849)' => sub { - plan tests => 5; + plan tests => 8; # Current userenv: userid == 42 my $result = Koha::Token::_add_default_csrf_params({ session_id => '567' }); @@ -133,4 +133,15 @@ subtest 'testing _add_default_csrf_params with/without userenv (bug 27849)' => s $result = Koha::Token::_add_default_csrf_params({}); # pass no session_id is( $result->{session_id}, Koha::Token::DEFA_SESSION_ID, 'Check session id' ); is( $result->{id}, Koha::Token::DEFA_SESSION_USERID. '_'. $result->{session_id}, 'Check userid' ); + + # Empty anonymous userenv (see C4::Auth::check_cookie_auth) + C4::Context->_new_userenv('ANON SESSION'); + C4::Context->set_userenv( undef, q{} ); + ok( C4::Context->userenv, "Userenv exists" ); + $result = Koha::Token::_add_default_csrf_params( {} ); # pass no session_id + is( $result->{session_id}, Koha::Token::DEFA_SESSION_ID, 'Check session id for anon session' ); + is( + $result->{id}, Koha::Token::DEFA_SESSION_USERID . '_' . $result->{session_id}, + 'Check userid for anon session' + ); }; -- 2.39.5