Executing Commands Without Shell Escapes
Problem
You need to use a user’s input as part of a command, but you
don’t want to allow the user to make the shell run other
commands or look at other files. If you just blindly call the
system
function or
backticks on a single string containing a command line, the shell
might be used to run the command. This would be unsafe.
Solution
Unlike its single-argument version, the list form of the
system
function is safe from shell escapes. When
the command’s arguments involve user input from a form, never
use this:
system("command $input @files"); # UNSAFE
Write it this way instead:
system("command", $input, @files); # safer
Discussion
Because Perl was designed as a glue language, it’s easy to use it to call other programs—too easy, in some cases.
If you’re merely trying to run a shell command but don’t
need to capture its output, it’s easy enough to call
system
using its multiple argument form. But what
happens if you’re using the command in backticks or as part of
a piped open? Now you have a real problem, because those don’t
permit the multiple argument form that system
does. The solution is to manually
fork
and
exec
the child processes on your own. It’s
more work, but at least stray shell escapes won’t be ruining
your day.
It’s safe to use backticks in a CGI script only if the arguments you give the program are purely internally generated, as in:
chomp($now = `date`);
But if the command within the backticks contains user-supplied input, perhaps ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.