I stumbled over a nasty bug in CGI.pm today. The kind of bug that surprises me not only because it's there, but because I never stumbled over it sooner. Turns out if you try to pass a '-' (dash) as a URL parameter value, and your script is running with the 'T' (taint) flag, then CGI->new dies with:
Insecure dependency in require while running with -T switch at /usr/lib/perl5/vendor_perl/5.10.0/CGI.pm line 516
This happens in version 3.33 (which I'm running) and doesn't appear to be corrected in the latest 3.42 version. A bug report was posted Mar 25 of this year, so at least I'm not the first to hit it. The problem boils down to this particular section of code:
496: sub init { ... 516: for my $fh (grep {defined(fileno($_))} @$val) { 517: seek($fh,0,0); # reset the filehandle. 518: }
The init() function walks through all query parameters and attempts to reset the file handle for each file name matching the parameter value. The parameter values are obviously tainted as they come from outside the script so using them as input to fileno() already has a funny smell to it. The init() function is called by the new() function, so near as I can tell, this only affects you if you if you use the object interface to CGI (my $obj = CGI->new). Maybe that's one reason why more people aren't complaining?
But CGI doesn't die on all URL values, just '-'. I did a little more digging and sure enough fileno() is called with every URL value, but only '-' caused an insecure dependancy compaint. So I wrote up a script so I could test further:
#!/usr/bin/perl -T use strict; use warnings; # snipped directly from CGI.pm # $val comes from (tained) URL parameters this this case # I'm using command line input to provide tainted test input my $val = \@ARGV; for my $fh (grep {defined(fileno($_))} @$val) { seek($fh,0,0); # reset the filehandle. }
Go ahead, try it yourself. I can pass all kinds of tainted values to fileno(), and none of them are flagged, except '-'.
So my observations are:
My solution is to pass a value into new, "my $obj = CGI->new('')", which is enough to trigger a different logic path which doesn't involve reseting file handles (it doesn't matter that the parameter passed into new is empty, just that it's defined).
But I feel there are questions that need answering here:
In reply to fileno, taint and CGI.pm by ruzam
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |