How to mitigate Command Injection Vulnerabilities
Introduction:
In the previous articles of this series, we discussed various topics around Command Injection vulnerabilities. We began by understanding what Command Injection vulnerabilities are and how they occur. We then discussed how one can exploit Command Injection vulnerabilities. In this article, we will discuss how to mitigate Command Injection vulnerabilities.
Learn Secure Coding
Use builtin APIs instead of OS commands
As we noticed in the earlier articles, Command injection occurs due to the fact that code is written to execute OS commands and an attacker can manipulate this behaviour to execute more commands than what the system is intended for. To prevent such vulnerabilities, one of the primary defenses developers should use it to avoid executing OS commands and use APIs provided by the framework or the language. For instance, to get the system date, instead of executing the following:
system(date);
?>
The developers should use the following.
echo date('l jS \of F Y h:i:s A');
?>
This will help the developers prevent command injection vulnerabilities due to the fact that the data function doesn't execute anything other than getting the date.
Input validation
Lack of input validation is the primary culprit of most of the web vulnerabilities and Command Injection is one of them. Command Injection vulnerabilities can be prevented using proper input validation. Developers must use a whitelisting approach to validate the user input. It can often be achieved using regular expressions. In the following example, the variable $target just expects an IP Address and it must be properly validated to ensure that the received data is indeed an IP Address.
// Get input
$target = $_REQUEST[ 'ip' ];
// Execute user input
$cmd = shell_exec( 'ping -c 4 ' . $target );
// Show the response back to the user
echo $cmd;
?>
The following IP Address validation code snippet taken from DVWA impossible level, shows that the IP Address should be properly validated before passing it to shell_exec function.
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects
$octet = explode( ".", $target );
// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
// Execute user input
$cmd = shell_exec( 'ping -c 4 ' . $target );
// Show the response back to the user
echo $cmd;
}
?>
Escaping shell metacharacters
As mentioned in the earlier articles, in most cases we will terminate the existing commands using shell metacharacters and then execute commands of our choice when exploiting Command Injection vulnerabilities. In these situations, escaping shell metacharacters can be used to prevent command execution vulnerabilities. Let us consider the following example.
// Get input
$target = $_REQUEST[ 'ip' ];
// Execute user input
$cmd = shell_exec( 'ping -c 4 ' . escapeshellarg($target));
// Show the response back to the user
echo $cmd;
?>
The preceding code snippet shows that the user supplied input is first passed to escapeshellarg function and then it is passed to shell_exec function. When an IP Address is passed to it, it works just fine.
However, if we pass any additional commands using shell metacharacters, it won't be processed by the application as shown below.
Though, all the examples in the article are shown using PHP programming language, they can be applied to other languages such as Java and .NET.
Learn Secure Coding
Conclusion:
Command Injection vulnerabilities may not exist commonly in every single application, but they can cause the worst damage when exploited by an attacker. As we have seen, they give completed control on the underlying host and it is extremely important for developers to be aware of Command Injection vulnerabilities. This article has provided some examples of how Command Injection vulnerabilities. As demonstrated, the best way to avoid Command Injection vulnerabilities is to avoid the use of execution of OS commands. When it cannot be avoided, proper input validation must be implemented preferably using a whitelisting approach.
Sources:
- https://owasp.org/www-community/attacks/Command_Injection
- https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html
- https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/12-Testing_for_Command_Injection