| home / programming / perl / taint | [previous] |
|
I mentioned earlier that variables that are set with values that are retrieved
from outside of your script will be considered tainted. This is true both
of variables that you are explicitly setting within your script, as well
as variables that you inherit that were set from information outside the
script. Among the key variables affected in this way are the environment
variables (i.e., accessed through the %ENV hash), and one
particular environment variable that deserves special mention in this
regard is the PATH environment variable.
Since your system calls rely on the setting of the PATH
variable (i.e., the command itself will be found based on the PATH setting),
when Taint Mode is on Perl will not let you execute system,
exec, or backtick (`OScommand`) calls unless you
first explicitly set the PATH within your script. Not only this,
the PATH that you set must include directories that are writable
only by their owner users and owner group, not by all users. In many cases,
scripts with Taint Mode enabled will simply clear the path, like this:
$ENV{"PATH"} = "";
# following would be an error if taint
# mode is enabled and path wasn't explicitly
# set or cleared
print `/usr/opt/echo "Hello World!"`;
The reason for this is that it may be possible that a malicious
user has reset your path to point to a set of dubious applications that
have the same names as the common applications that you are referring
to within your script. Thus, your script may find--and execute--those
malicious applications unwittingly. Note that Perl doesn't care if you
refer to the application with a fully qualified pathname, either; it
will still disallow the action if the PATH hasn't been
cleaned. This is because Perl doesn't know what the application you
are accessing will do with the faulty PATH setting;
thus it defaults to being overly protective and refusing the operation
entirely.
In some environments, you may also need to clear or set the following variables before executing system calls, as they also can have an effect on how the system call is processed:
IFSCDPATHENVBASH_ENVOne other environment-related concern is worth mentioning here. As I
discussed in an earlier tutorial
that introduced you to the use of modules in Perl scripts, the @INC
array includes a list of directories that Perl will use to search for
the modules used within your script. When Taint Mode is enabled, Perl
automatically removes the dot (".") entry from this list; so that the
search mechanism will not automatically search the current directory
for required library files (again, a malicious user could slip a dubious
module with the same name in your current directory that could be
loaded instead of the one you intended). For similar reasons, the
PERL5LIB and PERLLIB environment variables will
be ignored. Finally, if you assign to @INC a new directory that
is the result of a tainted variable, then you will receive an "Insecure
Dependency..." error.
In no paticular order, here are some last minute taint tips and facts that may be useful and/or trip you up if you aren't aware of them.
Beginning with version 5.8 of Perl, you can execute your script with
a version of Taint Mode that will just report insecure operations as warnings,
as opposed to crashing the script. You do this by using a lower case -t
instead of the normal upper case -T. This feature could be used to
debug an application; but it shouldn't be used in production
scripts, where it's better to be safe and simply disallow tainted operations
entirely.
Also in Perl 5.8, the variable ${^TAINT} can be accessed to tell you whether or not your script is running in Taint Mode.
In earlier examples I demonstrated how command line arguments, Web
form arguments, and environment variables are all considered tainted by Perl
when Taint Mode is activated; but these are not the only references that
are tainted. As listed in perlsec, others include locale information
and the expressions that it affects; results from readdir() and
readlink(); the variable of shmread(); the messages
returned by msgrcv(); the password, gcos
and shell fields returned by getpwxxx() calls and all
file input. Thus, any data you read in from a file is by default tainted.
Variable values used as symbolic method and subroutine references (as well as the arguments passed to such routines) are not checked for taintedness before the referenced routine is called, i.e.:
my $foo = shift;
# though tainted, the routine referenced by name in
# $foo will be executed, with the remaining arguments
# passed from the command line.
${$foo}(@ARGV);
Though the code executed as the result of the symbolic reference will itself check the taintedness of any variables it relies on, such a construct as above could still be used by an attacker to branch your program off in directions you did not intend; with no warnings from Taint Mode.
Earlier we mentioned that any variables in a subexpression of an expression that involves tainted data will themselves be tainted; but this does not apply to expressions in a ternary operation (unless the sub-expression in the ternary operation refers to the tainted variable). I.E.:
my $foo = shift;
# After the next statement, $bar is
# not tainted, even though $foo is
my $bar = ($foo=~/bar/) ? "foobar" : "nobar";
# However, after this statement $bar will be
# tainted if $foo contains "bar" but not
# otherwise
$bar = ($foo=~/bar/) ? $foo : "nobar";print and syswrite AllowedThough you can't open a file for writing where the name is provided via a tainted variable, you can write tainted data to any file. I.E., this will crash in taint mode:
my $foo = shift;
open (MYFILE, ">$foo");
But this is allowed:
my $foo = shift;
open (MYFILE, ">somefile.txt");
print MYFILE $foo;As mentioned earlier, Perl's Taint Mode will not, in and of itself, force you to write secure scripts; but it may force you to at least think about the security of your script (as well as prevent you from unknowingly introducing some known security risks). I encourage you to take advantage of this built-in security mechanism within your own scripts.
| home / programming / perl / taint | [previous] |
Created: April 18, 2006
Revised: May 5, 2006
URL: http://webreference.com/programming/perl/taint/2.html