Lines 28-33
use base qw(Koha::Object);
Link Here
|
28 |
# Only 1 error is returned |
28 |
# Only 1 error is returned |
29 |
# TODO Koha::Report->store should check this before saving |
29 |
# TODO Koha::Report->store should check this before saving |
30 |
|
30 |
|
|
|
31 |
use constant FORBIDDEN_COLUMN_MATCHES => qw(password token uuid secret); |
32 |
use constant WHITELISTED_COLUMN_NAMES => |
33 |
qw(password_expiration_date password_expiry_days reset_password change_password min_password_length require_strong_password password_expiration_date); |
34 |
|
31 |
=head1 NAME |
35 |
=head1 NAME |
32 |
|
36 |
|
33 |
Koha::Report - Koha Report Object class |
37 |
Koha::Report - Koha Report Object class |
Lines 58-68
sub is_sql_valid {
Link Here
|
58 |
push @errors, { sqlerr => $1 }; |
62 |
push @errors, { sqlerr => $1 }; |
59 |
} elsif ($sql !~ /^\s*SELECT\b\s*/i) { |
63 |
} elsif ($sql !~ /^\s*SELECT\b\s*/i) { |
60 |
push @errors, { queryerr => 'Missing SELECT' }; |
64 |
push @errors, { queryerr => 'Missing SELECT' }; |
|
|
65 |
} else { |
66 |
push @errors, { passworderr => "Illegal column in results" } |
67 |
if $self->check_columns($sql); |
61 |
} |
68 |
} |
62 |
|
69 |
|
63 |
return ( @errors ? 0 : 1, \@errors ); |
70 |
return ( @errors ? 0 : 1, \@errors ); |
64 |
} |
71 |
} |
65 |
|
72 |
|
|
|
73 |
=head3 check_columns |
74 |
|
75 |
$self->check_columns('SELECT password from borrowers'); |
76 |
$self->check_columns( undef, [qw(password token)] ); |
77 |
|
78 |
Check if passed sql statement or column_names arrayref contains |
79 |
forbidden column names (credentials etc.). |
80 |
Returns all bad column names or empty list. |
81 |
|
82 |
=cut |
83 |
|
84 |
sub check_columns { |
85 |
my ( $self, $sql, $column_names ) = @_; |
86 |
|
87 |
# TODO When passing sql, we actually go thru the whole statement, not just columns |
88 |
|
89 |
my $regex; |
90 |
push my @columns, @{ $column_names // [] }; |
91 |
if ($sql) { |
92 |
|
93 |
# Now find all matches for e.g. password but also modulepassword or password_hash |
94 |
# Note that \w includes underscore, not hyphen |
95 |
$regex = '(\w*(?:' . ( join '|', FORBIDDEN_COLUMN_MATCHES ) . ')\w*)'; |
96 |
@columns = ( $sql =~ /$regex/ig ); |
97 |
} else { |
98 |
$regex = '(' . ( join '|', FORBIDDEN_COLUMN_MATCHES ) . ')'; |
99 |
@columns = grep { /$regex/i } @columns; |
100 |
} |
101 |
|
102 |
# Check for whitelisted variants |
103 |
$regex = '(^' . ( join '|', WHITELISTED_COLUMN_NAMES ) . ')$'; # should be full match |
104 |
@columns = grep { !/$regex/i } @columns; |
105 |
return @columns; |
106 |
} |
107 |
|
66 |
=head3 get_search_info |
108 |
=head3 get_search_info |
67 |
|
109 |
|
68 |
Return search info |
110 |
Return search info |