home *** CD-ROM | disk | FTP | other *** search
-
-
-
- PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((RRRReeeelllleeeeaaaasssseeee 0000....0000 PPPPaaaattttcccchhhhlllleeeevvvveeeellll 00000000)))) PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
-
-
-
- NNNNAAAAMMMMEEEE
- perlsec - Perl security
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- Perl is designed to make it easy to write secure setuid and
- setgid scripts. Unlike shells, which are based on multiple
- substitution passes on each line of the script, Perl uses a
- more conventional evaluation scheme with fewer hidden
- "gotchas". Additionally, since the language has more
- built-in functionality, it has to rely less upon external
- (and possibly untrustworthy) programs to accomplish its
- purposes.
-
- Beyond the obvious problems that stem from giving special
- privileges to such flexible systems as scripts, on many
- operating systems, setuid scripts are inherently insecure
- right from the start. This is because that between the time
- that the kernel opens up the file to see what to run, and
- when the now setuid interpreter it ran turns around and
- reopens the file so it can interpret it, things may have
- changed, especially if you have symbolic links on your
- system.
-
- Fortunately, sometimes this kernel "feature" can be
- disabled. Unfortunately, there are two ways to disable it.
- The system can simply outlaw scripts with the setuid bit
- set, which doesn't help much. Alternately, it can simply
- ignore the setuid bit on scripts. If the latter is true,
- Perl can emulate the setuid and setgid mechanism when it
- notices the otherwise useless setuid/gid bits on Perl
- scripts. It does this via a special executable called
- ssssuuuuiiiiddddppppeeeerrrrllll that is automatically invoked for you if it's
- needed.
-
- If, however, the kernel setuid script feature isn't
- disabled, Perl will complain loudly that your setuid script
- is insecure. You'll need to either disable the kernel
- setuid script feature, or put a C wrapper around the script.
- See the program wwwwrrrraaaappppssssuuuuiiiidddd in the _e_g directory of your Perl
- distribution for how to go about doing this.
-
- There are some systems on which setuid scripts are free of
- this inherent security bug. For example, recent releases of
- Solaris are like this. On such systems, when the kernel
- passes the name of the setuid script to open to the
- interpreter, rather than using a pathname subject to
- mettling, it instead passes /dev/fd/3. This is a special
- file already opened on the script, so that there can be no
- race condition for evil scripts to exploit. On these
- systems, Perl should be compiled with
- -DSETUID_SCRIPTS_ARE_SECURE_NOW. The CCCCoooonnnnffffiiiigggguuuurrrreeee program that
- builds Perl tries to figure this out for itself.
-
-
-
- Page 1 (printed 6/30/95)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((RRRReeeelllleeeeaaaasssseeee 0000....0000 PPPPaaaattttcccchhhhlllleeeevvvveeeellll 00000000)))) PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
-
-
-
- When Perl is executing a setuid script, it takes special
- precautions to prevent you from falling into any obvious
- traps. (In some ways, a Perl script is more secure than the
- corresponding C program.) Any command line argument,
- environment variable, or input is marked as "tainted", and
- may not be used, directly or indirectly, in any command that
- invokes a subshell, or in any command that modifies files,
- directories, or processes. Any variable that is set within
- an expression that has previously referenced a tainted value
- also becomes tainted (even if it is logically impossible for
- the tainted value to influence the variable). For example:
-
- $foo = shift; # $foo is tainted
- $bar = $foo,'bar'; # $bar is also tainted
- $xxx = <>; # Tainted
- $path = $ENV{'PATH'}; # Tainted, but see below
- $abc = 'abc'; # Not tainted
-
- system "echo $foo"; # Insecure
- system "/bin/echo", $foo; # Secure (doesn't use sh)
- system "echo $bar"; # Insecure
- system "echo $abc"; # Insecure until PATH set
-
- $ENV{'PATH'} = '/bin:/usr/bin';
- $ENV{'IFS'} = '' if $ENV{'IFS'} ne '';
-
- $path = $ENV{'PATH'}; # Not tainted
- system "echo $abc"; # Is secure now!
-
- open(FOO,"$foo"); # OK
- open(FOO,">$foo"); # Not OK
-
- open(FOO,"echo $foo|"); # Not OK, but...
- open(FOO,"-|") || exec 'echo', $foo; # OK
-
- $zzz = `echo $foo`; # Insecure, zzz tainted
-
- unlink $abc,$foo; # Insecure
- umask $foo; # Insecure
-
- exec "echo $foo"; # Insecure
- exec "echo", $foo; # Secure (doesn't use sh)
- exec "sh", '-c', $foo; # Considered secure, alas
-
- The taintedness is associated with each scalar value, so
- some elements of an array can be tainted, and others not.
-
- If you try to do something insecure, you will get a fatal
- error saying something like "Insecure dependency" or
- "Insecure PATH". Note that you can still write an insecure
- system call or exec, but only by explicitly doing something
- like the last example above. You can also bypass the
-
-
-
- Page 2 (printed 6/30/95)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((RRRReeeelllleeeeaaaasssseeee 0000....0000 PPPPaaaattttcccchhhhlllleeeevvvveeeellll 00000000)))) PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
-
-
-
- tainting mechanism by referencing subpatterns--Perl presumes
- that if you reference a substring using $1, $2, etc, you
- knew what you were doing when you wrote the pattern:
-
- $ARGV[0] =~ /^-P(\w+)$/;
- $printer = $1; # Not tainted
-
- This is fairly secure since \w+ doesn't match shell
- metacharacters. Use of /.+/ would have been insecure, but
- Perl doesn't check for that, so you must be careful with
- your patterns. This is the _O_N_L_Y mechanism for untainting
- user supplied filenames if you want to do file operations on
- them (unless you make $> equal to $< ).
-
- For "Insecure PATH" messages, you need to set $ENV{'PATH}'
- to a known value, and each directory in the path must be
- non-writable by the world. A frequently voiced gripe is
- that you can get this message even if the pathname to an
- executable is fully qualified. But Perl can't know that the
- executable in question isn't going to execute some other
- program depending on the PATH.
-
- It's also possible to get into trouble with other operations
- that don't care whether they use tainted values. Make
- judicious use of the file tests in dealing with any user-
- supplied filenames. When possible, do opens and such after
- setting $> = $<. (Remember group IDs, too!) Perl doesn't
- prevent you from opening tainted filenames for reading, so
- be careful what you print out. The tainting mechanism is
- intended to prevent stupid mistakes, not to remove the need
- for thought.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 3 (printed 6/30/95)
-
-
-
-