Bug 34513

Summary: Authenticated users can bypass permissions and view some privileged pages
Product: Koha Reporter: Nick Clemens (kidclamp) <nick>
Component: Architecture, internals, and plumbingAssignee: David Cook <dcook>
Status: CLOSED FIXED QA Contact: Marcel de Rooy <m.de.rooy>
Severity: blocker    
Priority: P1 - high CC: 1joynelson, chris, dcook, didier.gautheron, evelyn, fridolin.somers, jonathan.druart, laurent.ducos, liz, lucas, m.de.rooy, martin.renvoize, nick, tomascohen, wizzyrea
Version: unspecified   
Hardware: All   
OS: All   
Change sponsored?: --- Patch complexity: Small patch
Documentation contact: Documentation submission:
Text to go in the release notes:
Version(s) released in:
23.11.00,23.05.04,22.11.10,22.05.16
Circulation function:
Attachments: Bug 34513: Set auth state correctly when changing auth sessions
Bug 34513: Add end-to-end test for authorization check after first failed authorization
Bug 34513: Add checkauth unit test for resetting auth state when changing users
Bug 34513: Set auth state correctly when changing auth sessions
Bug 34513: Add end-to-end test for authorization check after first failed authorization
Bug 34513: Add checkauth unit test for resetting auth state when changing users
Bug 34513: (QA follow-up) Tidy
Bug 34513: Set auth state correctly when changing auth sessions
Bug 34513: Add end-to-end test for authorization check after first failed authorization
Bug 34513: Add checkauth unit test for resetting auth state when changing users
Bug 34513: (QA follow-up) Tidy

Description Nick Clemens (kidclamp) 2023-08-10 11:53:30 UTC
This was found by a user when encountering bug 34449

If an unprivileged user performs a syspref search as on that bug they will be sent to an auth screen

Repeatedly enter their credentials, and then try leaving the password blank once, credntials again, then enter just a wrong username

Randomly, but consistently, you will eventually load the syspref search. Verified multiple times in 22.11 and master

I was able to view sysprefs, and attemtped to load a patron, which failed because the code died checking if other users could be seen, but the logged in patron was undefined.
Comment 1 Nick Clemens (kidclamp) 2023-08-10 14:17:30 UTC
Further testing - it seems if you simply enter an invalid username when you get the permissions needed log in, you get in every time
Comment 2 David Cook 2023-08-10 23:40:11 UTC Comment hidden (obsolete)
Comment 3 David Cook 2023-08-10 23:46:59 UTC Comment hidden (obsolete)
Comment 4 David Cook 2023-08-10 23:50:19 UTC Comment hidden (obsolete)
Comment 5 David Cook 2023-08-10 23:54:07 UTC Comment hidden (obsolete)
Comment 6 David Cook 2023-08-11 00:09:56 UTC Comment hidden (obsolete)
Comment 7 David Cook 2023-08-11 00:21:10 UTC Comment hidden (obsolete)
Comment 8 David Cook 2023-08-11 01:08:58 UTC Comment hidden (obsolete)
Comment 9 David Cook 2023-08-11 03:06:58 UTC
Created attachment 154357 [details] [review]
Bug 34513: Set auth state correctly when changing auth sessions

This patch sets the $auth_state to failed when changing auth sessions,
so that the new login attempt gets processed correctly (instead
of skipping the authorization step).

Test plan:
0. Apply the patch
1. koha-plack --reload kohadev
2. Go to
http://localhost:8081/cgi-bin/koha/admin/preferences.pl?tab=&op=search&searchfield=baseurl
3. Log in as an OPAC user with 0 permissions
4. Note the auth screen "Error: You do not have permission to access this page"
5. Click "Log in"
6. Note that you're still shown a login screen (and that you've been logged out of
your previous authenticated session)
Comment 10 Fridolin Somers 2023-08-11 22:48:16 UTC
After that,

Maybe we should create for access denied a different page than auth page.
Simply an alert text, 'previous page' button and a link to auth page (Log in as a different user).
Comment 11 David Cook 2023-08-13 23:14:19 UTC
(In reply to Fridolin Somers from comment #10)
> After that,
> 
> Maybe we should create for access denied a different page than auth page.
> Simply an alert text, 'previous page' button and a link to auth page (Log in
> as a different user).

That's a good point. I've had people say to me "Koha logged me out" and I've had to say to them "No, it says you're not authorized to view that page".

So it probably would be a good idea to clarify the not authorized screen.
Comment 12 David Cook 2023-08-13 23:14:48 UTC
I know everyone's travelling for Kohacon, but this would be a really good one to get tested and pushed!

It's a 1 line fix which closes up a massive hole.
Comment 13 Jonathan Druart 2023-08-14 05:35:03 UTC
We need tests...
Comment 14 David Cook 2023-08-14 06:43:21 UTC
(In reply to Jonathan Druart from comment #13)
> We need tests...

In general or for this change?

I think that a lot of our AuthN and AuthZ code is needlessly complex. 

A lot of our code could be condensed down into two simple AuthN and AuthZ steps like I've previously done here: https://bugs.koha-community.org/bugzilla3/page.cgi?id=splinter.html&bug=31380&attachment=144969

First we authenticate and then we authorize. If we can't authenticate, then we can't authorize (unless the authorization step is explicitly that no authorization is required).
Comment 15 Jonathan Druart 2023-08-14 11:54:58 UTC
(In reply to David Cook from comment #14)
> (In reply to Jonathan Druart from comment #13)
> > We need tests...
> 
> In general or for this change?

We need tests for this change.
Comment 16 Jonathan Druart 2023-08-14 12:01:56 UTC
I have quickly written that, thinking it would fail on master but it passes.

subtest "foo" => sub {
    plan tests => 3;

    my $patron   = $builder->build_object( { class => 'Koha::Patrons', value => { flags => 4 } } ); 
    my $password = 'password';
    t::lib::Mocks::mock_preference( 'RequireStrongPassword', 0 ); 
    $patron->set_password( { password => $password } ); 

    my $cgi_mock = Test::MockModule->new('CGI');
    $cgi_mock->mock( 'request_method', sub { return 'POST' } ); 

    my $cgi = CGI->new;
    my $auth = Test::MockModule->new( 'C4::Auth' );
    $auth->mock( 'safe_exit', sub { return } ); 


    $cgi->param( 'userid',   $patron->userid );
    $cgi->param( 'password', $password );

    # Logged in!
    my ( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 0, { catalogue => 1 } ); 
    is( $userid, $patron->userid );

    my $first_sessionID = $sessionID;

    ( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 0, { borrowers => 1 } ); 
    is( $userid, undef);
    isnt( $sessionID, $first_sessionID);
};
Comment 17 Jonathan Druart 2023-08-14 12:02:51 UTC
We have quite good testing in t/db_dependent/selenium/authentication.t if you prefer to prove end-to-end tests. But ideally we should have both.
Comment 18 Jonathan Druart 2023-08-14 14:32:35 UTC
The test is wrong. I did not set the sessionid in HTTP_COOKIE env var.
Comment 19 David Cook 2023-08-16 02:02:18 UTC
(In reply to Jonathan Druart from comment #17)
> We have quite good testing in t/db_dependent/selenium/authentication.t if
> you prefer to prove end-to-end tests. But ideally we should have both.

I've never managed to get the kohadev-intra.mydnsname.org stuff to work with k-t-d. Maybe I should have another crack at that...
Comment 20 David Cook 2023-08-16 02:08:25 UTC
(In reply to Jonathan Druart from comment #17)
> We have quite good testing in t/db_dependent/selenium/authentication.t if
> you prefer to prove end-to-end tests. But ideally we should have both.

Ok I've got those running now. I'll look at providing a test for that...
Comment 21 David Cook 2023-08-16 02:28:39 UTC
Created attachment 154439 [details] [review]
Bug 34513: Add end-to-end test for authorization check after first failed authorization
Comment 22 David Cook 2023-08-16 02:58:49 UTC
Created attachment 154440 [details] [review]
Bug 34513: Add checkauth unit test for resetting auth state when changing users
Comment 23 David Cook 2023-08-16 03:15:06 UTC
Both those tests will fail on master but succeed with this patch.
Comment 24 Chris Cormack 2023-08-18 09:36:15 UTC
I get a fail on the tests with the patch applied

#   Failed test 'Trying to change to a non-existent user should fail login'
    #   at /kohadevbox/koha/t/db_dependent/selenium/authentication.t line 61.
     #                   'Error: Can't use an undefined value as a HASH reference at /kohadevbox/koha/mainpage.pl line 93'
    #     doesn't match '(?^u:Invalid username or password)'
     # Looks like you failed 1 test of 7.
Comment 25 David Cook 2023-08-20 23:11:40 UTC
(In reply to Chris Cormack from comment #24)
> I get a fail on the tests with the patch applied
> 
> #   Failed test 'Trying to change to a non-existent user should fail login'
>     #   at /kohadevbox/koha/t/db_dependent/selenium/authentication.t line 61.
>      #                   'Error: Can't use an undefined value as a HASH
> reference at /kohadevbox/koha/mainpage.pl line 93'
>     #     doesn't match '(?^u:Invalid username or password)'
>      # Looks like you failed 1 test of 7.

Did you restart your Starman after applying the patch? That's the error you should see for an unpatched Koha. 

Looking back, it looks like I forgot to provide a test plan. If I recall correctly, it goes something like this:

Test plan:
0. Apply patch
1. koha-plack --restart kohadev
2. perl /kohadevbox/koha/t/db_dependent/selenium/authentication.t
Comment 26 David Cook 2023-08-24 06:32:10 UTC
Hoping that some folk can look at this once they're back from Kohacon.
Comment 27 Nick Clemens (kidclamp) 2023-08-24 18:21:16 UTC
Created attachment 154743 [details] [review]
Bug 34513: Set auth state correctly when changing auth sessions

This patch sets the $auth_state to failed when changing auth sessions,
so that the new login attempt gets processed correctly (instead
of skipping the authorization step).

Test plan:
0. Apply the patch
1. koha-plack --reload kohadev
2. Go to
http://localhost:8081/cgi-bin/koha/admin/preferences.pl?tab=&op=search&searchfield=baseurl
3. Log in as an OPAC user with 0 permissions
4. Note the auth screen "Error: You do not have permission to access this page"
5. Click "Log in"
6. Note that you're still shown a login screen (and that you've been logged out of
your previous authenticated session)

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Comment 28 Nick Clemens (kidclamp) 2023-08-24 18:21:19 UTC
Created attachment 154744 [details] [review]
Bug 34513: Add end-to-end test for authorization check after first failed authorization

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Comment 29 Nick Clemens (kidclamp) 2023-08-24 18:21:21 UTC
Created attachment 154745 [details] [review]
Bug 34513: Add checkauth unit test for resetting auth state when changing users

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Comment 30 Nick Clemens (kidclamp) 2023-08-24 18:21:23 UTC
Created attachment 154746 [details] [review]
Bug 34513: (QA follow-up) Tidy
Comment 31 Marcel de Rooy 2023-08-25 08:44:37 UTC
QA: Looking here now
Comment 32 Marcel de Rooy 2023-08-25 08:56:17 UTC
Created attachment 154781 [details] [review]
Bug 34513: Set auth state correctly when changing auth sessions

This patch sets the $auth_state to failed when changing auth sessions,
so that the new login attempt gets processed correctly (instead
of skipping the authorization step).

Test plan:
0. Apply the patch
1. koha-plack --reload kohadev
2. Go to
http://localhost:8081/cgi-bin/koha/admin/preferences.pl?tab=&op=search&searchfield=baseurl
3. Log in as an OPAC user with 0 permissions
4. Note the auth screen "Error: You do not have permission to access this page"
5. Click "Log in"
6. Note that you're still shown a login screen (and that you've been logged out of
your previous authenticated session)

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Comment 33 Marcel de Rooy 2023-08-25 08:56:20 UTC
Created attachment 154782 [details] [review]
Bug 34513: Add end-to-end test for authorization check after first failed authorization

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Comment 34 Marcel de Rooy 2023-08-25 08:56:23 UTC
Created attachment 154783 [details] [review]
Bug 34513: Add checkauth unit test for resetting auth state when changing users

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Comment 35 Marcel de Rooy 2023-08-25 08:56:25 UTC
Created attachment 154784 [details] [review]
Bug 34513: (QA follow-up) Tidy

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Comment 36 Marcel de Rooy 2023-08-25 08:57:43 UTC
Did not test Selenium. But could reproduce undesired behavior without patch and could no longer with patch.
Comment 37 Marcel de Rooy 2023-08-25 08:58:20 UTC
 OK     C4/Auth.pm
   OK     critic
   OK     forbidden patterns
   OK     git manipulation
   OK     pod
   OK     pod coverage
   SKIP   spelling
   OK     tidiness
   OK     valid

 OK     t/db_dependent/Auth.t
   OK     critic
   OK     forbidden patterns
   OK     git manipulation
   OK     pod
   SKIP   spelling
   OK     tidiness
   OK     valid

 OK     t/db_dependent/selenium/authentication.t
   OK     critic
   OK     forbidden patterns
   OK     git manipulation
   OK     pod
   SKIP   spelling
   OK     tidiness
   OK     valid

Joubu: no word about spelling :)
Comment 38 David Cook 2023-08-27 23:40:25 UTC
Much appreciated folks :)
Comment 39 Tomás Cohen Arazi (tcohen) 2023-09-25 22:09:11 UTC
Pushed to master for 23.11.

Nice work everyone, thanks!