=item *
-If you pass a list of arguments to either C<system> or C<exec>,
-the elements of that list are B<not> checked for taintedness.
+Arguments to C<print> and C<syswrite> are B<not> checked for taintedness.
=item *
-Arguments to C<print> and C<syswrite> are B<not> checked for taintedness.
+Symbolic methods
+
+ $obj->$method(@args);
+
+and symbolic sub references
+
+ &{$foo}(@args);
+ $foo->(@args);
+
+are not checked for taintedness. This requires extra carefulness
+unless you want external data to affect your control flow. Unless
+you carefully limit what these symbolic values are, people are able
+to call functions B<outside> your Perl code, such as POSIX::system,
+in which case they are able to run arbitrary external code.
=back
-Any variable set to a value
-derived from tainted data will itself be tainted, even if it is
-logically impossible for the tainted data to alter the variable.
+The value of an expression containing tainted data will itself be
+tainted, even if it is logically impossible for the tainted data to
+affect the value.
+
Because taintedness is associated with each scalar value, some
elements of an array can be tainted and others not.
$data = 'abc'; # Not tainted
system "echo $arg"; # Insecure
- system "/bin/echo", $arg; # Secure (doesn't use sh)
+ system "/bin/echo", $arg; # Considered insecure
+ # (Perl doesn't know about /bin/echo)
system "echo $hid"; # Insecure
system "echo $data"; # Insecure until PATH set
open(FOO, "< $arg"); # OK - read-only file
open(FOO, "> $arg"); # Not OK - trying to write
- open(FOO,"echo $arg|"); # Not OK, but...
+ open(FOO,"echo $arg|"); # Not OK
open(FOO,"-|")
- or exec 'echo', $arg; # OK
+ or exec 'echo', $arg; # Also not OK
$shout = `echo $arg`; # Insecure, $shout now tainted
unlink $data, $arg; # Insecure
umask $arg; # Insecure
- exec "echo $arg"; # Insecure (uses the shell)
- exec "echo", $arg; # Secure (doesn't use the shell)
- exec "sh", '-c', $arg; # Considered secure, alas!
+ exec "echo $arg"; # Insecure
+ exec "echo", $arg; # Insecure
+ exec "sh", '-c', $arg; # Very insecure!
@files = <*.c>; # insecure (uses readdir() or similar)
@files = glob('*.c'); # insecure (uses readdir() or similar)
# either case the result is tainted since the list of filenames comes
# from outside of the program.
+ $bad = ($arg, 23); # $bad will be tainted
+ $arg, `true`; # Insecure (although it isn't really)
+
If you try to do something insecure, you will get a fatal error saying
-something like "Insecure dependency" or "Insecure $ENV{PATH}". Note that you
-can still write an insecure B<system> or B<exec>, but only by explicitly
-doing something like the "considered secure" example above.
+something like "Insecure dependency" or "Insecure $ENV{PATH}".
=head2 Laundering and Detecting Tainted Data
Or you may be able to use the following I<is_tainted()> function.
sub is_tainted {
- return ! eval {
- join('',@_), kill 0;
- 1;
- };
+ return ! eval { eval("#" . substr(join("", @_), 0, 0)); 1 };
}
This function makes use of the fact that the presence of tainted data
if ($data =~ /^([-\@\w.]+)$/) {
$data = $1; # $data now untainted
} else {
- die "Bad data in $data"; # log this somewhere
+ die "Bad data in '$data'"; # log this somewhere
}
This is fairly secure because C</\w+/> doesn't normally match shell
best way to call something that might be subjected to shell escapes: just
never call the shell at all.
- use English;
+ use English '-no_match_vars';
die "Can't fork: $!" unless defined($pid = open(KID, "-|"));
if ($pid) { # parent
while (<KID>) {
blah." You should see a lawyer to be sure your licence's wording will
stand up in court.
+=head2 Unicode
+
+Unicode is a new and complex technology and one may easily overlook
+certain security pitfalls. See L<perluniintro> for an overview and
+L<perlunicode> for details, and L<perlunicode/"Security Implications
+of Unicode"> for security implications in particular.
+
=head1 SEE ALSO
L<perlrun> for its description of cleaning up environment variables.