Escaping Shell Metacharacters






Escaping Shell Metacharacters

Problem

You need to incorporate external data in a command line, but you want to escape special characters so nothing unexpected happens; for example, you want to pass user input as an argument to a program.

Solution

Use escapeshellarg( ) to handle arguments and escapeshellcmd( ) to handle program names, as in Figure.

Escaping shell metacharacters

<?php
system('ls -al '.escapeshellarg($directory));
system(escapeshellcmd($ls_program).' -al');
?>

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). Figure uses escapeshellarg( ) in printing the process status for a particular process.

Using escapeshellarg( )

<?php
system('/bin/ps '.escapeshellarg($process_id));
?>

Using escapeshellarg( ) ensures that the right process is displayed even if its ID 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 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. The command system("/usr/local/bin/formatter-$which_program"); runs a different program depending on the value of $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.

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.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows