in reply to Re^2: perl SQL injection prevent module
in thread perl SQL injection prevent module
(Update: just noticed the later reply from tantarbobus -- heed that as well.)perl -T your_script [args...]
That might be overkill, because it will cause perl to complain (and the script to die) if any variable derived from outside the script is used to affect anything else outside the script. This should include passing tainted variables to DBI calls, along with a wide variety of other things. See perlsec for more details about taint-checking.
If you go that route, you'll probably end up fixing a lot of other things besides potential SQL injection attacks. And maybe this would be a Good Thing -- if such attacks are a serious concern for you, then there might be other things to worry about as well. It'll end up being "invasive", but better that you should be the invader than someone else. ;)
You might want to do some triage on the script, to assess how much work needs to be done: just grep through the code for calls to the DBI methods that pass SQL text (prepare, do, select.*), to see how many different variables are being passed to these methods. (If all these calls involve string constants, you're done -- no room for injection attacks in that case.) Then you have to track down where and how values are being assigned to those variables.
If you are seeing a lot of situations like this:
You'll want to change those to:$sql = "select * from some_table where some_col = $target"; $sth = $dbh->prepare( $sql ); $sth->execute; ...
But if variables are being used like this:$sql = "select * from some_table where some_col = ?"; $sth = $dbh->prepare( $sql ); $sth->execute( $target );
and those variables are set by input from untrusted sources, then the only real protection is to untaint those values.$sql = "select $colum from $table";
Probably the best way is to set up a hash of column names and/or table names as needed (or a hash of whole query strings), then check each input to see if its value exists as a hash key. If so, use the hash value (which originates in your own code and so can be trusted) in order to form the query -- e.g.:
(update: added the necessary quotes around hash value assignments in this code snippet.)my $cols = ( foo => 'foo', bar => 'bar', baz => 'baz' ); my $tbls = ( parts => 'parts', table2 => 'table2' ); my $inp_col = <USER>; # get data from untrusted sources my $inp_tbl = $ENV{TABLE}; if ( exists( $cols{$inp_col} ) and exists( $tbls{$inp_tbl} ) { my $sql = "select $cols{$inp_col} from $tbls{$inp_tbl}"; # now it's safe to run the query... }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: perl SQL injection prevent module
by Anonymous Monk on Nov 21, 2008 at 23:12 UTC |