This post covers the Remote Code Injection section of the PHP Security chapter when studying for the Zend PHP 7 Certification.
Remote code injection, also known as remote file inclusion attacks, run malicious code created by an attacker on a given server. This is often done by exploiting the functionality of PHP’s
require() functions, or by not sanitising data as a result of using
Consider the following example:
$incfile = $_REQUEST["file"]; include($incfile.".php");
The path is extracted from the HTTP request and no input validation is done (for example, by checking the input against a white list).
Therefore, the file parameter could include something like the following:
In this case the remote file is going to be included and any code contained in it is going to be run by the server.
You should never pass untrusted user input to
unserialize() as unserialising can result in code being loaded and executed due to object instantiation and autoloading, and a malicious user may be able to exploit this.
$incfile = $_REQUEST["file"]; unserialize(file_get_contents($incFile));
In PHP 7.0, a second
option parameter can be passed into
unserialize(), which can either be an
allowed_classes array of class names which should be accepted,
FALSE to accept no classes, or
TRUE to accept all classes.
This can help protect against remote code injection as only the classes whitelisted within the array can be unserialised. However, it should be noted that you should never trust user input regardless of having an
$data = unserialize($incFile, ["allowed_classes" => ["MyClass1", "MyClass2"]]);
system() are all vulnerable to remote code injection.
Fortunately there are counter measures that can be put in place. These include:
basename()function returns the trailing name component of path.
allow_url_fopento off in
php.ini, which otherwise allows files to be included from external sources.
json_encode()) if you need to pass serialised data to the user.
Other counter measures include the use of the
escapeshellarg() function adds single quotes around a string and quotes/escapes any existing single quotes allowing you to pass a string directly to a shell function and having it be treated as a single safe argument.
<?php system('ls '.escapeshellarg($dir));
escapeshellcmd() function escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands.
// We allow arbitrary number of arguments intentionally here. $command = './configure '.$_POST['configure_options']; $escaped_command = escapeshellcmd($command); system($escaped_command);
View the other sections:
Note: This article is based on PHP version 7.0