X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlsec.pod;h=41f96691aca4905d665c752766fa6d87f27ebaed;hb=6bdd71ef1830fa9fb85306405e4da0222df1321d;hp=18c25eee44718af801ca9e0e5e1e06f69eff1e99;hpb=83df6a1d65c0fba9c27c7fb715fa674b03462cf0;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlsec.pod b/pod/perlsec.pod index 18c25ee..41f9669 100644 --- a/pod/perlsec.pod +++ b/pod/perlsec.pod @@ -44,18 +44,31 @@ directories, or processes, B: =item * -If you pass a list of arguments to either C or C, -the elements of that list are B checked for taintedness. +Arguments to C and C are B checked for taintedness. =item * -Arguments to C and C are B 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 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. @@ -71,7 +84,8 @@ For example: $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 @@ -86,9 +100,9 @@ For example: 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 @@ -96,29 +110,33 @@ For example: umask $arg; # Insecure exec "echo $arg"; # Insecure - exec "echo", $arg; # Secure (doesn't use the shell) - exec "sh", '-c', $arg; # Considered secure, alas! + 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) + # In Perl releases older than 5.6.0 the <*.c> and glob('*.c') would + # have used an external program to do the filename expansion; but in + # 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 or B, 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 -To test whether a variable contains tainted data, and whose use would thus -trigger an "Insecure dependency" message, check your nearby CPAN mirror -for the F module, which should become available around November -1997. Or you may be able to use the following I function. +To test whether a variable contains tainted data, and whose use would +thus trigger an "Insecure dependency" message, you can use the +tainted() function of the Scalar::Util module, available in your +nearby CPAN mirror, and included in Perl starting from the release 5.8.0. +Or you may be able to use the following I 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 @@ -146,7 +164,7 @@ or a dot. 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 doesn't normally match shell @@ -230,7 +248,7 @@ not called with a string that the shell could expand. This is by far the 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 () { @@ -361,6 +379,82 @@ Your access to it does not give you permission to use it blah blah 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 for an overview and +L for details, and L for security implications in particular. + +=head2 Algorithmic Complexity Attacks + +Certain internal algorithms used in the implementation of Perl can +be attacked by choosing the input carefully to consume large amounts +of either time or space or both. This can lead into the so-called +I (DoS) attacks. + +=over 4 + +=item * + +Hash Function - the algorithm used to "order" hash elements has been +changed several times during the development of Perl, mainly to be +reasonably fast. In Perl 5.8.1 also the security aspect was taken +into account. + +In Perls before 5.8.1 one could rather easily generate data that as +hash keys would cause Perl to consume large amounts of time because +internal structure of hashes would badly degenerate. In Perl 5.8.1 +the hash function is randomly perturbed by a pseudorandom seed which +makes generating such naughty hash keys harder. +See L for more information. + +The random perturbation is done by default but if one wants for some +reason emulate the old behaviour one can set the environment variable +PERL_HASH_SEED to zero (or any other integer). One possible reason +for wanting to emulate the old behaviour is that in the new behaviour +consecutive runs of Perl will order hash keys differently, which may +confuse some applications (like Data::Dumper: the outputs of two +different runs are no more identical). + +B, and the +ordering has already changed several times during the lifetime of +Perl 5. Also, the ordering of hash keys has always been, and +continues to be, affected by the insertion order. + +Also note that while the order of the hash elements might be +randomised, this "pseudoordering" should B be used for +applications like shuffling a list randomly (use List::Util::shuffle() +for that, see L, a standard core module since Perl 5.8.0; +or the CPAN module Algorithm::Numerical::Shuffle), or for generating +permutations (use e.g. the CPAN modules Algorithm::Permute or +Algorithm::FastPermute), or for any cryptographic applications. + +=item * + +Regular expressions - Perl's regular expression engine is so called +NFA (Non-Finite Automaton), which among other things means that it can +rather easily consume large amounts of both time and space if the +regular expression may match in several ways. Careful crafting of the +regular expressions can help but quite often there really isn't much +one can do (the book "Mastering Regular Expressions" is required +reading, see L). Running out of space manifests itself by +Perl running out of memory. + +=item * + +Sorting - the quicksort algorithm used in Perls before 5.8.0 to +implement the sort() function is very easy to trick into misbehaving +so that it consumes a lot of time. Nothing more is required than +resorting a list already sorted. Starting from Perl 5.8.0 a different +sorting algorithm, mergesort, is used. Mergesort is insensitive to +its input data, so it cannot be similarly fooled. + +=back + +See L for more information, +and any computer science text book on the algorithmic complexity. + =head1 SEE ALSO L for its description of cleaning up environment variables.