G'day Raymond and Dave,

Warning: Self-promotion ahead.  ;)

I both love and hate taint mode, have written about it extensively, and
presented a tutorial at OSCON that covered it in depth.  Our "Perl Security"
manual includes a lot of details about what taint protects you from, and
more importantly, what it doesn't protect you from.  You can download it from:

        http://perltraining.com.au/notes.html

The release on the website is presently the same as the OSCON tutorial
notes.  There's a chapter that covers calling system commands in some depth,
as well as path attacks, random numbers, and other gotchas.

Dave Rolsky wrote:

> In the particular case of using system() or exec(), the #1 most important 
> thing to do is to make sure that you call it with a list of arguments:
> 
>   system( $cmd, @args );
> 
> This ensures that Perl will _not_ pass this command to your system's shell 
> for execution. Avoiding the shell avoids all the problems of things like 
> semi-colons, etc.

This is excellent advice.  Unfortunately Perl will *still* use the shell is
@args is empty.  Under Windows, Perl will decide to use the shell anyway if
it can't find $cmd (and sometimes under other circumstances as well).  Under
older versions of Perl (at least 5.6.1 and before) the multi-arg system
didn't check its arguments for taint, weakening that mechanism if you use it.

I recommend:

        use IPC::System::Simple qw(systemx);

And then using systemx($cmd, @args).  The systemx() call never uses the
shell and always checks for taint (if enabled), even if @args is empty, even
if you're using Windows, and even if you're on an older version of Perl.
It'll also die loudly if your command doesn't start, is killed by a signal,
or returns an unexpected exit value.

The IPC::System::Simple module is available from the CPAN, has no
dependencies, and works on everything back to 5.6.0.  I also wrote it and
use it everywhere, so I think it's wonderful. ;)

> Also, this does not protect you from users doing things like putting 
> "../../../../../../../../../etc/shadow" as an argument and seeing what 
> happens. This you still have to handle yourself.

Clever use of File::Spec can provide assistance here:

        # Make sure it is not an absolute filename (don't want /etc/passwd)
        if( File::Spec->file_name_is_absolute( $filename ) ) {
                die "Absolute paths in filenames are not allowed";
        }

        # Make sure that we're not trying to walk up the file tree
        my $updir = File::Spec->updir();
        if( grep {$_ eq $updir} File::Spec->splitdir($filename) ) {
                die "Attempts to backtrack are not allowed";
        }

That should spot both attempts to detect absolute paths and traversal
attacks in a relatively system-independent fashion.  It's a good candidate
for dropping into a subroutine.

Cheerio,

        Paul

-- 
Paul Fenwick <[EMAIL PROTECTED]> | http://perltraining.com.au/
Director of Training                   | Ph:  +61 3 9354 6001
Perl Training Australia                | Fax: +61 3 9354 2681

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Mason-users mailing list
Mason-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mason-users

Reply via email to