Recipe 18.21 Escaping Shell Metacharacters
18.21.1 Problem
You need to
incorporate external data in a command line, but
you want to escape out special characters so nothing unexpected
happens; for example, you want to pass user input as an argument to a
program.
18.21.2 Solution
Use escapeshellarg(
) to handle arguments:
system('ls -al '.escapeshellarg($directory));
Use escapeshellcmd( ) to handle program names:
system(escapeshellcmd($ls_program).' -al');
18.21.3 Discussion
The command line is a dangerous place
for unescaped characters. Never pass unmodified user input to one of
PHP's
shell-execution functions.
Always escape the appropriate characters in the command and the
arguments. This is crucial. It is unusual to execute command lines
that are coming from web forms and not something we recommend
lightly. However, sometimes you need to run an external program, so
escaping commands and arguments is useful.
escapeshellarg( ) surrounds arguments with
single quotes (and
escapes any existing single quotes). To print the process status for
a particular process:
system('/bin/ps '.escapeshellarg($process_id));
Using escapeshellarg( ) ensures that the right
process is displayed even if it has an unexpected character (e.g., a
space) in it. It also prevents unintended commands from being run. If
$process_id contains:
1; rm -rf /
then:
system("/bin/ps $process_id")
not only displays the status of process 1, but it also executes the
command rm -rf /. However:
system('/bin/ps '.escapeshellarg($process_id))
runs the command /bin/ps 1; rm -rf, which
produces an error because
"1-semicolon-space-rm-space-hyphen-rf"
isn't a valid process ID.
Similarly, escapeshellcmd( ) prevents unintended
command lines from execution. This code runs a different program
depending on the value of $which_program:
system("/usr/local/bin/formatter-$which_program");
For example, if $which_program is pdf
12, the script runs
/usr/local/bin/formatter-pdf with an argument of
12. But, if $which_program is
pdf 12; 56, the script runs
/usr/local/bin/formatter-pdf with an argument of
12, but then also runs the program
56, which is an error. To successfully pass the
arguments to
formatter-pdf, you need escapeshellcmd(
):
system(escapeshellcmd("/usr/local/bin/formatter-$which_program"));
This runs /usr/local/bin/formatter-pdf and
passes it two arguments: 12 and
56.
18.21.4 See Also
Documentation on system( ) at http://www.php.net/system,
escapeshellarg( ) at http://www.php.net/escapeshellarg, and
escapeshellcmd( ) at http://www.php.net/escapeshellcmd.
|