X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=rt%2Flib%2FRT%2FSearchBuilder.pm;fp=rt%2Flib%2FRT%2FSearchBuilder.pm;h=ec4a223c07be7fcd946351d65b00cd96e238c0e7;hb=01f60974743197ac14e569c16c68a0c2ff3a5bd4;hp=da542ea4ebe220222273c1e972983e047e33a264;hpb=b5c4237a34aef94976bc343c8d9e138664fc3984;p=freeside.git diff --git a/rt/lib/RT/SearchBuilder.pm b/rt/lib/RT/SearchBuilder.pm index da542ea4e..ec4a223c0 100644 --- a/rt/lib/RT/SearchBuilder.pm +++ b/rt/lib/RT/SearchBuilder.pm @@ -85,6 +85,17 @@ sub _Init { $self->SUPER::_Init( 'Handle' => $RT::Handle); } +sub OrderByCols { + my $self = shift; + my @sort; + for my $s (@_) { + next if defined $s->{FIELD} and $s->{FIELD} =~ /\W/; + $s->{FIELD} = $s->{FUNCTION} if $s->{FUNCTION}; + push @sort, $s; + } + return $self->SUPER::OrderByCols( @sort ); +} + =head2 LimitToEnabled Only find items that haven't been disabled @@ -274,14 +285,47 @@ This Limit sub calls SUPER::Limit, but defaults "CASESENSITIVE" to 1, thus making sure that by default lots of things don't do extra work trying to match lower(colname) agaist lc($val); +We also force VALUE to C when the OPERATOR is C or C. +This ensures that we don't pass invalid SQL to the database or allow SQL +injection attacks when we pass through user specified values. + =cut sub Limit { my $self = shift; - my %args = ( CASESENSITIVE => 1, - @_ ); + my %ARGS = ( + CASESENSITIVE => 1, + OPERATOR => '=', + @_, + ); - return $self->SUPER::Limit(%args); + # We use the same regex here that DBIx::SearchBuilder uses to exclude + # values from quoting + if ( $ARGS{'OPERATOR'} =~ /IS/i ) { + # Don't pass anything but NULL for IS and IS NOT + $ARGS{'VALUE'} = 'NULL'; + } + + if ($ARGS{FUNCTION}) { + ($ARGS{ALIAS}, $ARGS{FIELD}) = split /\./, delete $ARGS{FUNCTION}, 2; + $self->SUPER::Limit(%ARGS); + } elsif ($ARGS{FIELD} =~ /\W/ + or $ARGS{OPERATOR} !~ /^(=|<|>|!=|<>|<=|>= + |(NOT\s*)?LIKE + |(NOT\s*)?(STARTS|ENDS)WITH + |(NOT\s*)?MATCHES + |IS(\s*NOT)? + |IN)$/ix) { + $RT::Logger->crit("Possible SQL injection attack: $ARGS{FIELD} $ARGS{OPERATOR}"); + $self->SUPER::Limit( + %ARGS, + FIELD => 'id', + OPERATOR => '<', + VALUE => '0', + ); + } else { + $self->SUPER::Limit(%ARGS); + } } =head2 ItemsOrderBy @@ -345,9 +389,6 @@ sub _DoCount { return $self->SUPER::_DoCount(@_); } -eval "require RT::SearchBuilder_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/SearchBuilder_Vendor.pm}); -eval "require RT::SearchBuilder_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/SearchBuilder_Local.pm}); +RT::Base->_ImportOverlays(); 1;