Bug 22990: Add CSRF protection to boraccount, pay and suggestion

Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Test plan would have been nioe.
Tested by changing MAX_AGE with suggestions.
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
(cherry picked from commit 833d1dc8b082cc742b88e358edef77960b5ffc2f)
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
(cherry picked from commit 0c365b52f474e0fc0dd439f11bfa0a95534db029)
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@ptfs-europe.com>
This commit is contained in:
Amit Gupta 2020-01-22 21:37:22 +05:30 committed by Matt Blenkinsop
parent 27f44f461e
commit 416604e1e6
6 changed files with 37 additions and 12 deletions

View file

@ -44,7 +44,7 @@
[% INCLUDE 'members-toolbar.inc' %]
<h1>Account for [% INCLUDE 'patron-title.inc' %]</h1>
<form action="/cgi-bin/koha/members/boraccount.pl" method="get"><input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" /></form>
<form action="/cgi-bin/koha/members/boraccount.pl" method="get">[% INCLUDE 'csrf-token.inc' %]<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" /></form>
<!-- The manual invoice and credit buttons -->
<div class="toptabs">
@ -124,14 +124,14 @@
[% END %]
<a href="accountline-details.pl?accountlines_id=[% account.accountlines_id | uri %]" class="btn btn-default btn-xs details-action"><i class="fa fa-list"></i> Details</a>
[% IF account.is_debit && account.amountoutstanding > 0 %]
<a class="btn btn-default btn-xs pay-action" href="/cgi-bin/koha/members/paycollect.pl?borrowernumber=[% account.borrowernumber | html %]&pay_individual=1&debit_type_code=[% account.debit_type_code | html %]&amount=[% account.amount | html %]&amountoutstanding=[% account.amountoutstanding | html %]&description=[% account.description | html %]&itemnumber=[% account.itemnumber | html %]&accountlines_id=[% account.accountlines_id | html %]"><i class="fa fa-money"></i> Pay</a>
<a class="btn btn-default btn-xs pay-action" href="/cgi-bin/koha/members/paycollect.pl?borrowernumber=[% account.borrowernumber | html %]&pay_individual=1&debit_type_code=[% account.debit_type_code | html %]&amount=[% account.amount | html %]&amountoutstanding=[% account.amountoutstanding | html %]&description=[% account.description | html %]&itemnumber=[% account.itemnumber | html %]&accountlines_id=[% account.accountlines_id | html %]&amp;csrf_token=[% csrf_token | html %]"><i class="fa fa-money"></i> Pay</a>
[% END %]
[% IF account.is_credit && account.status != 'VOID' %]
<a href="boraccount.pl?action=void&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs void-action"><i class="fa fa-ban"></i> Void payment</a>
<a href="boraccount.pl?action=void&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]&amp;csrf_token=[% csrf_token | uri %]" class="btn btn-default btn-xs void-action"><i class="fa fa-ban"></i> Void payment</a>
[% END %]
[% IF account.is_debit && account.amount == account.amountoutstanding && account.status != 'CANCELLED' && !(account.debit_type_code == 'PAYOUT') %]
<form method="post" action="/cgi-bin/koha/members/cancel-charge.pl">
<input type="hidden" name="csrf_token" value="[% csrf_token | html %]">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]">
<input type="hidden" name="accountlines_id" value="[% account.accountlines_id | html %]">
<button type="submit" class="btn btn-default btn-xs cancel-action">
@ -187,6 +187,7 @@
<!-- Issue payout modal -->
<div class="modal" id="issuePayoutModal" tabindex="-1" role="dialog" aria-labelledby="issuePayoutLabel">
<form id="payout_form" action="/cgi-bin/koha/members/boraccount.pl" method="get" enctype="multipart/form-data" class="validated">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="accountlines_id" value="" id="payoutline">
<input type="hidden" name="action" value="payout">
<input type="hidden" name="borrowernumber" value="[% account.borrowernumber | html %]">
@ -241,6 +242,7 @@
<!-- Issue refund modal -->
<div class="modal" id="issueRefundModal" tabindex="-1" role="dialog" aria-labelledby="issueRefundLabel">
<form id="refund_form" action="/cgi-bin/koha/members/boraccount.pl" method="get" enctype="multipart/form-data" class="validated">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="accountlines_id" value="" id="refundline">
<input type="hidden" name="action" value="refund">
<input type="hidden" name="borrowernumber" value="[% account.borrowernumber | html %]">
@ -298,6 +300,7 @@
<!-- Apply discount modal -->
<div class="modal" id="applyDiscountModal" tabindex="-1" role="dialog" aria-labelledby="applyDiscountLabel">
<form id="discount_form" action="/cgi-bin/koha/members/boraccount.pl" method="get" enctype="multipart/form-data" class="validated">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="accountlines_id" value="" id="discountline">
<input type="hidden" name="action" value="discount">
<input type="hidden" name="borrowernumber" value="[% account.borrowernumber | html %]">

View file

@ -70,6 +70,7 @@
[% IF ( accounts ) %]
<form action="/cgi-bin/koha/members/pay.pl" method="post" id="pay-fines-form">
<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" />
[% INCLUDE 'csrf-token.inc' %]
<p><span class="checkall"><a id="CheckAll" href="#"><i class="fa fa-check"></i> Select all</a></span> | <span class="clearall"><a id="CheckNone" href="#"><i class="fa fa-remove"></i> Clear all</a></span></p>
<table id="finest">
<thead>

View file

@ -90,6 +90,8 @@
[% END #/ WRAPPER breadcrumbs %]
[% END #/ WRAPPER sub-header.inc %]
[% INCLUDE 'blocking_errors.inc' %]
[% IF ( op == 'show' ) %]
<div class="main container-fluid">
<div class="row">
@ -337,6 +339,7 @@
[% END %]
<form id="add_edit" action="suggestion.pl" method="post" class="validated">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="redirect" id="redirect" value="[% redirect | html %]" />
<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber | html %]" />
[% IF ( suggestionid ) %]
@ -709,6 +712,7 @@
[% FOREACH suggestion IN suggestions %]
[% WRAPPER tab_panel tabname= suggestion.suggestiontype %]
<form class="update_suggestions" name="f" method="post" action="/cgi-bin/koha/suggestion/suggestion.pl#[% suggestion.suggestiontype| uri %]">
[% INCLUDE 'csrf-token.inc' %]
[% IF suggestion.suggestions.size %]
<p>
@ -995,6 +999,7 @@
<div class="col-sm-2 col-sm-pull-10">
<aside>
<form name="suggestionfilter" action="suggestion.pl" method="get">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="branchcode" value="[% branchfilter | html %]" />
<fieldset class="brief">
<h4>Organize by:</h4>

View file

@ -69,6 +69,7 @@ output_and_exit_if_error( $input, $cookie, $template, { module => 'members', log
my $registerid = $input->param('registerid');
if ( $action eq 'void' ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $payment_id = scalar $input->param('accountlines_id');
my $payment = Koha::Account::Lines->find( $payment_id );
$payment->void(
@ -81,8 +82,10 @@ if ( $action eq 'void' ) {
}
if ( $action eq 'payout' ) {
my $payment_id = scalar $input->param('accountlines_id');
my $amount = scalar $input->param('amount');
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $payment_id = scalar $input->param('accountlines_id');
my $payment = Koha::Account::Lines->find($payment_id);
my $amount = scalar $input->param('amount');
my $payout_type = scalar $input->param('payout_type');
if ( $payment_id eq "" ) {
$schema->txn_do(
@ -119,9 +122,10 @@ if ( $action eq 'payout' ) {
}
if ( $action eq 'refund' ) {
my $charge_id = scalar $input->param('accountlines_id');
my $charge = Koha::Account::Lines->find($charge_id);
my $amount = scalar $input->param('amount');
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $charge_id = scalar $input->param('accountlines_id');
my $charge = Koha::Account::Lines->find($charge_id);
my $amount = scalar $input->param('amount');
my $refund_type = scalar $input->param('refund_type');
$schema->txn_do(
sub {
@ -152,6 +156,7 @@ if ( $action eq 'refund' ) {
}
if ( $action eq 'discount' ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $charge_id = scalar $input->param('accountlines_id');
my $charge = Koha::Account::Lines->find($charge_id);
my $amount = scalar $input->param('amount');

View file

@ -77,22 +77,28 @@ $user ||= q{};
our $branch = C4::Context->userenv->{'branch'};
if ( $input->param('paycollect') ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
print $input->redirect(
"/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber&change_given=$change_given");
}
elsif ( $input->param('payselected') ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
payselected({ params => \@names });
}
elsif ( $input->param('writeoff_selected') ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
payselected({ params => \@names, type => 'WRITEOFF' });
}
elsif ( $input->param('woall') ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
writeoff_all(@names);
}
elsif ( $input->param('apply_credits') ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
apply_credits({ patron => $patron, cgi => $input });
}
elsif ( $input->param('confirm_writeoff') ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $item_id = $input->param('itemnumber');
my $accountlines_id = $input->param('accountlines_id');
my $amount = $input->param('amountwrittenoff');
@ -129,9 +135,11 @@ elsif ( $input->param('confirm_writeoff') ) {
for (@names) {
if (/^pay_indiv_(\d+)$/) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $line_no = $1;
redirect_to_paycollect( 'pay_individual', $line_no );
} elsif (/^wo_indiv_(\d+)$/) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $line_no = $1;
redirect_to_paycollect( 'writeoff_individual', $line_no );
}

View file

@ -21,7 +21,7 @@ use Modern::Perl;
require Exporter;
use CGI qw ( -utf8 );
use C4::Auth qw( get_template_and_user );
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::Suggestions;
use C4::Koha qw( GetAuthorisedValues );
use C4::Budgets qw( GetBudget GetBudgets GetBudgetHierarchy CanUserUseBudget );
@ -133,6 +133,7 @@ my $branchfilter = $input->param('branchcode') || C4::Context->userenv->{'branch
##
if ( $op =~ /save/i ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my @messages;
my $biblio = MarcRecordFromNewSuggestion({
title => $suggestion_only->{title},
@ -250,7 +251,8 @@ elsif ($op=~/add/) {
$op ='save';
}
elsif ($op=~/edit/) {
#Edit suggestion
#Edit suggestion
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
$suggestion_ref=&GetSuggestion($$suggestion_ref{'suggestionid'});
$suggestion_ref->{reasonsloop} = $reasonsloop;
my $other_reason = 1;
@ -265,7 +267,7 @@ elsif ($op=~/edit/) {
$op ='save';
}
elsif ($op eq "update_status" ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
my $suggestion;
# set accepted/rejected/managed informations if applicable
# ie= if the librarian has chosen some action on the suggestions
@ -302,6 +304,7 @@ elsif ($op eq "update_status" ) {
}
redirect_with_params($input);
}elsif ($op eq "delete" ) {
output_and_exit_if_error($input, $cookie, $template, { check => 'csrf_token' });
foreach my $delete_field (@editsuggestions) {
&DelSuggestion( $borrowernumber, $delete_field,'intranet' );
}