From 1b59140ccac5668e9619f834974eeaefb00ad624 Mon Sep 17 00:00:00 2001 From: David Cook Date: Tue, 1 Aug 2023 06:56:23 +0000 Subject: [PATCH] Bug 34369: Require CSRF token for updating system preferences This patch adds the requirements that updating a system preference requires a CSRF token. (Also, adding and deleting local system preferences.) 0. Apply patch 1. koha-plack --reload kohadev 2. Add local system preference 3. Update local system preference 4. Delete local system preference 5. Update normal system preference 6. Note no errors Signed-off-by: Jonathan Druart Signed-off-by: Marcel de Rooy --- admin/preferences.pl | 3 ++- admin/systempreferences.pl | 5 ++++- .../prog/en/modules/admin/preferences.tt | 3 ++- .../prog/en/modules/admin/systempreferences.tt | 5 +++++ .../intranet-tmpl/prog/js/pages/preferences.js | 7 +++++++ svc/config/systempreferences | 14 ++++++++++++++ 6 files changed, 34 insertions(+), 3 deletions(-) diff --git a/admin/preferences.pl b/admin/preferences.pl index 9e697a6a03..7cc818ff46 100755 --- a/admin/preferences.pl +++ b/admin/preferences.pl @@ -25,7 +25,7 @@ use C4::Context; use C4::Koha qw( getallthemes ); use C4::Languages qw( getTranslatedLanguages ); use C4::ClassSource qw( GetClassSources GetClassSource ); -use C4::Output qw( output_html_with_http_headers ); +use C4::Output qw( output_html_with_http_headers output_and_exit_if_error ); use C4::Templates; use Koha::Acquisition::Currencies; use IO::File; @@ -346,6 +346,7 @@ $tab ||= 'accounting'; # Ideally this should be "local-use" but preferences.pl my $highlighted; if ( $op eq 'save' ) { + output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' }); foreach my $param ( $input->param() ) { my ( $pref ) = ( $param =~ /pref_(.*)/ ); diff --git a/admin/systempreferences.pl b/admin/systempreferences.pl index 1eb54552b1..d2d1369223 100755 --- a/admin/systempreferences.pl +++ b/admin/systempreferences.pl @@ -49,7 +49,7 @@ use C4::Context; use C4::Koha qw( getallthemes ); use C4::Languages qw( getTranslatedLanguages ); use C4::ClassSource qw( GetClassSources GetClassSource ); -use C4::Output qw( output_html_with_http_headers ); +use C4::Output qw( output_html_with_http_headers output_and_exit_if_error ); use YAML::XS; my %tabsysprefs; #we do no longer need to keep track of a tab per pref (yaml) @@ -235,6 +235,7 @@ if ($op) { } if ( $op eq 'update_and_reedit' ) { + output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' }); foreach ( $input->param ) { } my $value = ''; @@ -302,6 +303,7 @@ if ( $op eq 'add_form' ) { ################## ADD_VALIDATE ################################## # called by add_form, used to insert/modify data in DB } elsif ( $op eq 'add_validate' ) { + output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' }); # to handle multiple values my $value; @@ -348,6 +350,7 @@ if ( $op eq 'add_form' ) { ################## DELETE_CONFIRMED ################################## # called by delete_confirm, used to effectively confirm deletion of data in DB } elsif ( $op eq 'delete_confirmed' ) { + output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' }); C4::Context->delete_preference($searchfield); # END $OP eq DELETE_CONFIRMED ################## DEFAULT ################################## diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt index e9e624b82b..1cbbf8d626 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt @@ -55,7 +55,8 @@

[% TAB.tab_title | html %] preferences

- [% UNLESS ( searchfield ) %]
[% END %] + [% INCLUDE 'csrf-token.inc' %] + [% UNLESS ( searchfield ) %]
[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/systempreferences.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/systempreferences.tt index c769c72b81..fbc59454b8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/systempreferences.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/systempreferences.tt @@ -99,6 +99,8 @@ +[% INCLUDE 'blocking_errors.inc' %] +
@@ -110,6 +112,7 @@ [% ELSE %] [% END %] + [% INCLUDE 'csrf-token.inc' %]
[% IF ( modify ) %]Modify [% ELSE %]Add @@ -302,6 +305,7 @@ [% Tvalue | html %] + [% INCLUDE 'csrf-token.inc' %] @@ -349,6 +353,7 @@ [% ELSE %] [% END %] + [% INCLUDE 'csrf-token.inc' %] [% IF ( loo.type_free ) %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js b/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js index e7d8dad01a..d43237636b 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js +++ b/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js @@ -25,6 +25,13 @@ KOHA.Preferences = { humanMsg.displayAlert( __("Nothing to save") ); return; } + let csrf_token_el = $( form ).find('input[name="csrf_token"]'); + if (csrf_token_el.length > 0){ + let csrf_token = csrf_token_el.val(); + if (csrf_token){ + data += '&' + 'csrf_token=' + csrf_token; + } + } KOHA.AJAX.MarkRunning($(form).find('.save-all'), __("Saving...") ); KOHA.AJAX.Submit( { data: data, diff --git a/svc/config/systempreferences b/svc/config/systempreferences index acaf3e485f..c592594781 100755 --- a/svc/config/systempreferences +++ b/svc/config/systempreferences @@ -23,6 +23,7 @@ use Modern::Perl; use C4::Context; use C4::Service; use C4::Log; +use Koha::Token; =head1 NAME @@ -63,6 +64,12 @@ Used to set a single system preference. sub set_preference { my ( $preference ) = @_; + die "wrong_csrf_token\n" unless Koha::Token->new->check_csrf( + { + session_id => scalar $query->cookie('CGISESSID'), + token => scalar $query->param('csrf_token'), + } + ); my $value = join( ',', $query->param( 'value' ) ); C4::Context->set_preference( $preference, $value ); @@ -93,6 +100,13 @@ pref_virtualshelves=0 =cut sub set_preferences { + die "wrong_csrf_token\n" unless Koha::Token->new->check_csrf( + { + session_id => scalar $query->cookie('CGISESSID'), + token => scalar $query->param('csrf_token'), + } + ); + foreach my $param ( $query->param() ) { my ( $pref ) = ( $param =~ /pref_(.*)/ ); -- 2.20.1