Bug 37508: Throw error if password column is detected in SQL report
This enhancement prevents SQL queries from being run if they would return a password field from the database table. To test: 1. Run tests and notice they fail t/db_dependent/Reports/Guided.t 2. Apply patch and restart services 3. Create a public report with an SQL report which would access a password column in a database table 4. Try to run the report. Notice you are met with an error and the results are not shown. 5. Access the JSON URL, you should not get the results and should be shown an error 6. Confirm tests pass t/db_dependent/Reports/Guided.t Sponsored-by: Reserve Bank of New Zealand Signed-off-by: David Cook <dcook@prosentient.com.au> Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
parent
aec8c65336
commit
947865f83b
4 changed files with 43 additions and 5 deletions
|
@ -623,6 +623,13 @@ sub execute_query {
|
||||||
->info("Report finished: $report_id") if $report_id;
|
->info("Report finished: $report_id") if $report_id;
|
||||||
|
|
||||||
return ( $sth, { queryerr => $sth->errstr } ) if ( $sth->err );
|
return ( $sth, { queryerr => $sth->errstr } ) if ( $sth->err );
|
||||||
|
|
||||||
|
foreach my $column ( @{ $sth->{NAME_lc} } ) {
|
||||||
|
if ( $column eq 'password' ) {
|
||||||
|
return ( $sth, { passworderr => $column } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ($sth);
|
return ($sth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1443,6 +1443,10 @@
|
||||||
[% error.queryerr | html %]<br />Please check the log for further details.
|
[% error.queryerr | html %]<br />Please check the log for further details.
|
||||||
[% ELSIF ( error.cache_expiry ) %]
|
[% ELSIF ( error.cache_expiry ) %]
|
||||||
Please select a cache expiry less than 30 days.
|
Please select a cache expiry less than 30 days.
|
||||||
|
[% ELSIF ( error.passworderr ) %]
|
||||||
|
The column selection in this report includes a password field.<br>
|
||||||
|
The report cannot be executed due to security risks.<br>
|
||||||
|
Please edit this report and ensure no password columns have been selected.
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
[% END %]
|
[% END %]
|
||||||
<div id="onerror_actions">
|
<div id="onerror_actions">
|
||||||
|
|
|
@ -74,7 +74,9 @@ unless ($json_text) {
|
||||||
report_id => $report_id,
|
report_id => $report_id,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($sth) {
|
if ($errors) {
|
||||||
|
$json_text = encode_json($errors);
|
||||||
|
} else {
|
||||||
my $lines;
|
my $lines;
|
||||||
if ($report_annotation) {
|
if ($report_annotation) {
|
||||||
$lines = $sth->fetchall_arrayref({});
|
$lines = $sth->fetchall_arrayref({});
|
||||||
|
@ -88,9 +90,6 @@ unless ($json_text) {
|
||||||
$cache->set_in_cache( $cache_key, $json_text, { expiry => $report_rec->cache_expiry } );
|
$cache->set_in_cache( $cache_key, $json_text, { expiry => $report_rec->cache_expiry } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$json_text = encode_json($errors);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print $query->header(
|
print $query->header(
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
use Modern::Perl;
|
use Modern::Perl;
|
||||||
|
|
||||||
use Test::More tests => 11;
|
use Test::More tests => 12;
|
||||||
use Test::Warn;
|
use Test::Warn;
|
||||||
|
|
||||||
use t::lib::TestBuilder;
|
use t::lib::TestBuilder;
|
||||||
|
@ -499,6 +499,34 @@ subtest 'nb_rows() tests' => sub {
|
||||||
$schema->storage->txn_rollback;
|
$schema->storage->txn_rollback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
subtest 'Returning passwords tests' => sub {
|
||||||
|
|
||||||
|
plan tests => 3;
|
||||||
|
|
||||||
|
my $dbh = C4::Context->dbh;
|
||||||
|
$schema->storage->txn_begin;
|
||||||
|
|
||||||
|
my $query = q{ SELECT * FROM borrowers };
|
||||||
|
|
||||||
|
my ( $sth, $errors ) = execute_query( { sql => $query } );
|
||||||
|
|
||||||
|
is( defined($errors), 1, 'Query returns password field' );
|
||||||
|
|
||||||
|
$query = q{ SELECT * FROM z3950servers };
|
||||||
|
|
||||||
|
( $sth, $errors ) = execute_query( { sql => $query } );
|
||||||
|
|
||||||
|
is( defined($errors), 1, 'Query returns password field' );
|
||||||
|
|
||||||
|
$query = q{ SELECT password FROM deletedborrowers };
|
||||||
|
|
||||||
|
( $sth, $errors ) = execute_query( { sql => $query } );
|
||||||
|
|
||||||
|
is( defined($errors), 1, 'Query returns password field' );
|
||||||
|
|
||||||
|
$schema->storage->txn_rollback;
|
||||||
|
};
|
||||||
|
|
||||||
sub trim {
|
sub trim {
|
||||||
my ($s) = @_;
|
my ($s) = @_;
|
||||||
$s =~ s/^\s*(.*?)\s*$/$1/s;
|
$s =~ s/^\s*(.*?)\s*$/$1/s;
|
||||||
|
|
Loading…
Reference in a new issue