How to Prevent Command Injection in PHP

From WikiHTP

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[edit]

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[edit]

All command arguments must be escaped using escapeshellarg() or 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 rm.

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 exec, passthru, proc_open, shell_exec, and system. All must have their inputs carefully validated and escaped.


About This Tutorial

This page was last edited on 28 January 2019, at 06:36.