in reply to Apple, quoting, and system()

Good advice. Security can also be improved by using the safer "flavor" of system. If you pass system a string, it will use a sub-shell to figure out what that string means. This can easily be abused and is almost always overkill anyway.

It's safer to pass system a list. The first element will be treated as the program name to fork, the rest are params to said program. Perhaps a concrete example is best:

#!/usr/bin/perl -w use strict; # malicious input my $dir = '/tmp; echo "GOT YA"'; # system using shell print "AS STRING\n"; system("ls $dir"); # system w/o the shell print "\nAS LIST\n"; system('ls', $dir); =OUTPUT AS STRING [snip -- same as `ls /tmp`] GOT YA AS LIST ls: /tmp; echo "GOT YA": No such file or directory
Notice how 'ls /tmp; echo "GOT YA"' is parsed into two separate commands by the shell. By calling system in a safer way we can force everything in $dir to be treated as a filename.

-Blake

Replies are listed 'Best First'.
(tye)Re: Apple, quoting, and system()
by tye (Sage) on Nov 07, 2001 at 03:52 UTC

    Actually, Perl's system and exec only invoke a shell if you pass them a single string and that string contains shell meta characters.

    Note that this can still break things similar to the original story:

    my $root= "/usr/local "; # oops system( "rm -rf $root/lib" ); # goodbye /lib (and /usr/local) # However, if you instead do: system( "rm", "-rf", "$root/lib" ); # then nothing gets deleted unless # "/usr/local /lib" exists.
    Note that no shell is involved in the above problem.

            - tye (but my friends call me "Tye")