How to Prevent Command Injection in PHP
In a similar way that SQL injection allows an attacker to execute arbitrary queries on a database, command-line injection allows someone to run untrusted system commands on a web server. With an improperly secured server, this would give an attacker complete control over a system so that by using the following method learn how to prevent command line injection in PHP.
Understanding Command Injection
Let's say, for example, a script allows a user to list directory contents on a web server.
system('ls ' . $_GET['path']);
In a real-world application, one would use PHP's built-in functions or objects to get path contents. This example is for a simple security demonstration.
One would hope to get a
path parameter similar to
/tmp. But as any input is allowed,
path could be
; rm -fr /. The web server would then execute the command
ls; rm -fr /
and attempt to delete all files from the root of the server.
Prevent Command Injection
All command arguments must be escaped using
escapeshellcmd(). This makes the arguments non-executable. For each parameter, the input value should also be validated.
In the simplest case, we can secure our example with
system('ls ' . escapeshellarg($_GET['path']));
Following the previous example with the attempt to remove files, the executed command becomes
ls '; rm -fr /'
And the string is simply passed as a parameter to
ls, rather than terminating the
ls command and running
It should be noted that the example above is now secure from command injection, but not from directory traversal. To fix this, it should be checked that the normalized path starts with the desired sub-directory.
PHP offers a variety of functions to execute system commands, including
system. All must have their inputs carefully validated and escaped.