LP#1811685: qtype CGI parameter checking
authorMike Rylander <mrylander@gmail.com>
Thu, 17 Nov 2022 22:11:38 +0000 (17:11 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Thu, 23 Mar 2023 19:04:58 +0000 (15:04 -0400)
With this commit we throw away searches with invalid qtype value based
on configured classes and aliases.  Invalid qtype values have been seen
in the wild as part of attempted (but failed) SQL injection attacks, so
we will tighten up what we accept.

As an additional (unrelated) bonus, this commit also avoids prepending
the search class on basic search when the class (from qytpe) is not
exactly "keyword".

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Jason Stephenson <jason@sigio.com>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm
Open-ILS/src/templates-bootstrap/opac/parts/header.tt2
Open-ILS/src/templates/opac/parts/header.tt2

index bb845b2..81132be 100644 (file)
@@ -10,11 +10,23 @@ use Data::Dumper;
 $Data::Dumper::Indent = 0;
 my $U = 'OpenILS::Application::AppUtils';
 
+my @_qtype_list;
+
 sub _prepare_biblio_search_basics {
     my ($cgi) = @_;
 
     return scalar($cgi->param('query')) unless scalar($cgi->param('qtype'));
 
+    # fetch, once per mod_perl backend, the list of valid classes and aliases
+    unless (@_qtype_list) {
+        my $editor = new_editor();
+        my $classes = $editor->retrieve_all_config_metabib_class();
+        my $aliases = $editor->retrieve_all_config_metabib_search_alias();
+
+        push @_qtype_list, map { $_->name } @$classes;
+        push @_qtype_list, map { $_->alias } @$aliases;
+    }
+
     my %parts;
     my @part_names = qw/qtype contains query bool/;
     $parts{$_} = [ $cgi->param($_) ] for (@part_names);
@@ -42,6 +54,9 @@ sub _prepare_biblio_search_basics {
             $jtitle = 1;
         }
 
+        # This restricts qtype to classes, aliases, and field lists (approximately)
+        next unless grep { $qtype =~ /^$_(?:\|\w+)*$/ } @_qtype_list;
+
         # This stuff probably will need refined or rethought to better handle
         # the weird things Real Users will surely type in.
         $contains = "" unless defined $contains; # silence warning
index 4bda61e..52c6c77 100755 (executable)
@@ -9,7 +9,7 @@
     # Don't wrap in l() here; do that where this format string is actually used.
     SET HUMAN_NAME_FORMAT = '[_1] [_2] [_3] [_4] [_5]';
 
-    is_advanced = CGI.param("_adv").size || CGI.param("query").size;
+    is_advanced = CGI.param("_adv").size || CGI.param("query").size > 1;
     is_special = CGI.param("_special").size;
 
     # Check if we want to show the detail record view.  Doing this
index 2bf7bb0..804edcc 100644 (file)
@@ -9,7 +9,7 @@
     # Don't wrap in l() here; do that where this format string is actually used.
     SET HUMAN_NAME_FORMAT = '[_1] [_2] [_3] [_4] [_5]';
 
-    is_advanced = CGI.param("_adv").size || CGI.param("query").size;
+    is_advanced = CGI.param("_adv").size || CGI.param("query").size > 1;
     is_special = CGI.param("_special").size;
 
     # Check if we want to show the detail record view.  Doing this