ennuikiller has asked for the wisdom of the Perl Monks concerning the following question:

So, understanding the security implications involved in using backticks, what is the "best practice" preferred way of executing an external os command? What are the advantages of using the open my $fh, "$cmd|" as opposed to `$cmd`, and which would be considered more correct? Thanks!

Replies are listed 'Best First'.
Re: Best way to call external os command
by Anonymous Monk on Nov 01, 2010 at 19:21 UTC
    The main disadvantage (possible security risk) of using backticks or qx// is that it runs the command through the shell.

    This means that, for example, a user-supplied input parameter may contain special characters which change how the system executes the command string.

      but doesn't the same security risk exist if you use the filehandle form? I mean a user could as easily pass in some malicious code in $cmd using open($FH,"$cmd|") as in using `$cmd` or am I missing something?
        I mean a user could as easily pass in some malicious code in $cmd using open($FH,"$cmd|") as in using `$cmd` or am I missing something?

        The difference is that the pipe open supports a list form, so in open my $handle, "$cmd|", $arg1, $arg2 the $arg1 and $arg2 don't evaluate shell meta characters; if they are user-supplied, they generally can't execute arbitrary code.

        Whereas if you do `$cmd $arg1 $arg2`, and one of the arguments is user-supplied, having $arg1 = '; rm -rf ~/*' might cause much more damage.

        Perl 6 - links to (nearly) everything that is Perl 6.

        ennuikiller:

        Since the OP waived the security argument, I don't think that the AM was referring to security problems. Just the normal problems of differing shells doing different string munging before executing stuff is hairy enough. Depending on the shell, you'll have a different sequence of flaming hoops to leap through to ensure that your quotes, ampersands, exclamation marks, question marks, asterisks, etc. make it to the command rather than being intercepted and interpreted by a shell.

        If you don't know which shell your user is going to use, it can be challenging to come up with an appropriate string to put within your backticks.

        ...roboticus

        Update: ...and then after hitting the "create" button, I see the "security risk" in parens in the AM post. Sorry ennuikiller...

        If you are going to exec OS commands that are passed in, you should definitely enable taint mode, and inspect passed in values, maybe check file paths etc.