The taint mechanism tries to protect you from data supplied by a potentially hostile user. Such data can be trickily constructed to cause your program to malfunction and provide said user with access to which they are not entitled. You can ask perl to do taint checking at any time, but it automatically does it for setuid scripts.
Taint checking tracks the origin of all data used by your program. Data from untrusted sources is considered tainted, and may not be used as part of certain risky operations such as command lines, filenames, etc. The %ENV{} hash comes from shell environment variables, over which presumably the user has some control, and thus, they are tainted. Among the things in the hash is the search path for commands. If the user did something like "PATH=/home/eviluser/scripts:/bin:/usr/bin" then invoked your program, and your program executed something like "ls" without specifying a path, you might execute eviluser's undesirable ls script instead of /bin/ls. However, if taint checking is turned on, this can't happen. The way to work with the taint mechanism is to set the path explicitly at the beginning of your program. Do this with a string literal, to avoid further taint issues, and only put known-secure directories into the path. For example, you could do: $ENV{"PATH"} = "/bin:/usr/bin"; Other data which is not tied to system functionality, e.g. text you read from a file, can be de-tainted as follows: 1. Ensure the data is safe, possibly by stripping out any constructs which are not known to be safe 2. Use the following construct, which has the side effect of detainting: $untainted = ($tainted =~ /^(.*)$/); note that the pattern needs to match all of the data you want to keep. Dennis Boone MATRIX / Michigan State University > I just taint gettin' this taint thing. Please banish the darkness. > I've got a cgi program that makes a call to a homegrown package. The > homegrown package (I made successfully!) among several things tried to > run this: > $host = `hostname`; > ....and of course it failed with this message in apache's error_log: > 1) Insecure $ENV{PATH} while running setuid at > /home/Louis/Perlib/LOUIS_utility.pm line 62. > 2) Compilation failed in require at /home/Louis/Cgi-bin/lz0006.pl line 35. > 3) BEGIN failed--compilation aborted at /home/Louis/Cgi-bin/lz0006.pl line > 35. > So I do some research into taintness in the "Cookbook" and find a > receipe to untaint (with the regular caveats about security). I take > the following code and insert it in my package to accomplish > identifying the hostname, and guess what. My cgi program works but I > still get the exact same message in the error_log above even after I > "cp /dev/null" the error_log file in case I was looking at an old > message. Here's the receipe code: > die "cannot fork: $!" unless defined ($pid = open(SAFE, "|-")); > if ($pid == 0) { > exec('hostname') or die "can't exec hostname: $!"; > } else { > $host = <SAFE>; > close SAFE; > } > Perl baulks at the insecure env path in my package LOUIS_utility.pm > and the calling cgi program lz0006.pl fails to compile. And yet it > works! If somebody simply tells me that this is impossible, I will > take a break and a deep breadth.