in reply to Moving A Web Application From Hacky To ... Less Hacky

First of all, well done so far. You're nine-tenths of the way to being finished. Now you just have to make it pretty.

I'm gonna give you a crash course in tainting. Tainting is activated by the -T switch. What it basically does is it marks all data from outside your program as tainted:

my $from_outside=<STDIN>; my $from_inside='Hey!'; tainted($from_outside); #true tainted($from_inside); #false tainted($ENV{PATH}); #true
If one variable in an expression is tainted, the result of that whole expression is too:
tainted(($untainted1+$untainted2).$tainted); #true tainted(($untainted1+$untainted2).$untainted3); #false
Taintedness is for individual pieces of scalar data--some elements of an array or hash can be tainted without tainting the whole thing.

So, what does this taintedness do? Here's your answer:

open(FH, $tainted); system($tainted); `$tainted`; eval($tainted); exec($tainted);
All of those blow up. There are other functions that blow up too, but those are the biggies.

Tainting helps you keep track of what you're doing with data from the outside. The idea is that you don't trust anything that came from outside your program--at least not when it affects something else outside your program. After all, if $tainted were 'rm -rf /', three of those examples would have deleted all your files.

Of course, data from outside is sometimes trustable. Taint just makes you check that it's trustable. How? Well, the only way to remove a variable's taintedness is to get it out of a regular expression group.

For example, let's say I'm going to get part of a file name from the outside. I know that the only characters that should be in that part of the file name are \w characters, so I can do this:

if($file_name=~/^(\w+)$/) { $file_name=$1; #no longer tainted } open(FH, "> users/grades/$file_name") or die "Can't open grades for $f +ile_name: $!";
If $file_name matches the pattern, it gets untainted, but if it doesn't, it stays tainted. If it stays tainted, you'll get a fatal error like this: Insecure dependency in open while running with -T switch at script.pl line 4. There are two very important things to remember about taint checking.
  1. It is not a silver bullet. There are still many other things that the user could do which taint checking wouldn't catch. In that example, the untainted variable could refer to a file that doesn't exist, blowing your script out of the water.
  2. When writing your validation patterns, always specify what you want, never what you don't. For example, it's probably impossible to come up with a complete regular expression to filter all dangerous things out of shell command. However, if you know that they should only be using one of ten utilities, it's easy to check that they're using only those utilities.
This is just a quick overview. The perlsec manpage in your Perl distribution has a large section on tainting.

=cut
--Brent Dax
There is no sig.