perlsec.pod

来自「MSYS在windows下模拟了一个类unix的终端」· POD 代码 · 共 366 行 · 第 1/2 页

POD
366
字号
=head1 NAMEperlsec - Perl security=head1 DESCRIPTIONPerl is designed to make it easy to program securely even when runningwith extra privileges, like setuid or setgid programs.  Unlike mostcommand line shells, which are based on multiple substitution passes oneach line of the script, Perl uses a more conventional evaluation schemewith fewer hidden snags.  Additionally, because the language has morebuiltin functionality, it can rely less upon external (and possiblyuntrustworthy) programs to accomplish its purposes.Perl automatically enables a set of special security checks, called I<taintmode>, when it detects its program running with differing real and effectiveuser or group IDs.  The setuid bit in Unix permissions is mode 04000, thesetgid bit mode 02000; either or both may be set.  You can also enable taintmode explicitly by using the B<-T> command line flag. This flag isI<strongly> suggested for server programs and any program run on behalf ofsomeone else, such as a CGI script. Once taint mode is on, it's on forthe remainder of your script.While in this mode, Perl takes special precautions called I<taintchecks> to prevent both obvious and subtle traps.  Some of these checksare reasonably simple, such as verifying that path directories aren'twritable by others; careful programmers have always used checks likethese.  Other checks, however, are best supported by the language itself,and it is these checks especially that contribute to making a set-id Perlprogram more secure than the corresponding C program.You may not use data derived from outside your program to affectsomething else outside your program--at least, not by accident.  Allcommand line arguments, environment variables, locale information (seeL<perllocale>), results of certain system calls (readdir(),readlink(), the variable of shmread(), the messages returned bymsgrcv(), the password, gcos and shell fields returned by thegetpwxxx() calls), and all file input are marked as "tainted".Tainted data may not be used directly or indirectly in any commandthat invokes a sub-shell, nor in any command that modifies files,directories, or processes, B<with the following exceptions>:=over 4=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.=item *Arguments to C<print> and C<syswrite> are B<not> checked for taintedness.=backAny variable set to a valuederived from tainted data will itself be tainted, even if it islogically impossible for the tainted data to alter the variable.Because taintedness is associated with each scalar value, someelements of an array can be tainted and others not.For example:    $arg = shift;		# $arg is tainted    $hid = $arg, 'bar';		# $hid is also tainted    $line = <>;			# Tainted    $line = <STDIN>;		# Also tainted    open FOO, "/home/me/bar" or die $!;    $line = <FOO>;		# Still tainted    $path = $ENV{'PATH'};	# Tainted, but see below    $data = 'abc';		# Not tainted    system "echo $arg";		# Insecure    system "/bin/echo", $arg;	# Secure (doesn't use sh)    system "echo $hid";		# Insecure    system "echo $data";	# Insecure until PATH set    $path = $ENV{'PATH'};	# $path now tainted    $ENV{'PATH'} = '/bin:/usr/bin';    delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};    $path = $ENV{'PATH'};	# $path now NOT tainted    system "echo $data";	# Is secure now!    open(FOO, "< $arg");	# OK - read-only file    open(FOO, "> $arg"); 	# Not OK - trying to write    open(FOO,"echo $arg|");	# Not OK, but...    open(FOO,"-|")	or exec 'echo', $arg;	# OK    $shout = `echo $arg`;	# Insecure, $shout now tainted    unlink $data, $arg;		# Insecure    umask $arg;			# Insecure    exec "echo $arg";		# Insecure    exec "echo", $arg;		# Secure (doesn't use the shell)    exec "sh", '-c', $arg;	# Considered secure, alas!    @files = <*.c>;		# insecure (uses readdir() or similar)    @files = glob('*.c');	# insecure (uses readdir() or similar)If you try to do something insecure, you will get a fatal error sayingsomething like "Insecure dependency" or "Insecure $ENV{PATH}".  Note that youcan still write an insecure B<system> or B<exec>, but only by explicitlydoing something like the "considered secure" example above.=head2 Laundering and Detecting Tainted DataTo test whether a variable contains tainted data, and whose use would thustrigger an "Insecure dependency" message, check your nearby CPAN mirrorfor the F<Taint.pm> module, which should become available around November1997.  Or you may be able to use the following I<is_tainted()> function.    sub is_tainted {	return ! eval {	    join('',@_), kill 0;	    1;	};    }This function makes use of the fact that the presence of tainted dataanywhere within an expression renders the entire expression tainted.  Itwould be inefficient for every operator to test every argument fortaintedness.  Instead, the slightly more efficient and conservativeapproach is used that if any tainted value has been accessed within thesame expression, the whole expression is considered tainted.But testing for taintedness gets you only so far.  Sometimes you have justto clear your data's taintedness.  The only way to bypass the taintingmechanism is by referencing subpatterns from a regular expression match.Perl presumes that if you reference a substring using $1, $2, etc., thatyou knew what you were doing when you wrote the pattern.  That means usinga bit of thought--don't just blindly untaint anything, or you defeat theentire mechanism.  It's better to verify that the variable has only goodcharacters (for certain values of "good") rather than checking whether ithas any bad characters.  That's because it's far too easy to miss badcharacters that you never thought of.Here's a test to make sure that the data contains nothing but "word"characters (alphabetics, numerics, and underscores), a hyphen, an at sign,or a dot.    if ($data =~ /^([-\@\w.]+)$/) {	$data = $1; 			# $data now untainted    } else {	die "Bad data in $data"; 	# log this somewhere    }This is fairly secure because C</\w+/> doesn't normally match shellmetacharacters, nor are dot, dash, or at going to mean something specialto the shell.  Use of C</.+/> would have been insecure in theory becauseit lets everything through, but Perl doesn't check for that.  The lessonis that when untainting, you must be exceedingly careful with your patterns.Laundering data using regular expression is the I<only> mechanism foruntainting dirty data, unless you use the strategy detailed below to forka child of lesser privilege.The example does not untaint $data if C<use locale> is in effect,because the characters matched by C<\w> are determined by the locale.Perl considers that locale definitions are untrustworthy because theycontain data from outside the program.  If you are writing alocale-aware program, and want to launder data with a regular expressioncontaining C<\w>, put C<no locale> ahead of the expression in the sameblock.  See L<perllocale/SECURITY> for further discussion and examples.=head2 Switches On the "#!" LineWhen you make a script executable, in order to make it usable as acommand, the system will pass switches to perl from the script's #!line.  Perl checks that any command line switches given to a setuid(or setgid) script actually match the ones set on the #! line.  SomeUnix and Unix-like environments impose a one-switch limit on the #!line, so you may need to use something like C<-wU> instead of C<-w -U>under such systems.  (This issue should arise only in Unix orUnix-like environments that support #! and setuid or setgid scripts.)=head2 Cleaning Up Your PathFor "Insecure C<$ENV{PATH}>" messages, you need to set C<$ENV{'PATH'}> to aknown value, and each directory in the path must be non-writable by others

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?