Web Applications Security - What Is Command Line Injection?
Eyad Bereh
Software Engineer | Senior PHP & Laravel Developer | Master of Web Science Student at SVU
Introduction
In the previous article, we talked about SQL injection and demonstrated its damage and harmful effects. In this article, we will talk about another vulnerability that's less common but more destructive, the command line injection.
Command line injection is a type of security vulnerability that occurs when an attacker inserts malicious commands into a command-line interface (CLI) of a software application. The injected commands can then be executed with the privileges of the application or the user running it, potentially allowing the attacker to gain unauthorized access or control of the system.
How Does An Application Become Vulnerable?
The scenario is really simple. In PHP, the function shell_exec() can be used to execute a command line on the operating system's shell. For example, let's assume that we have a form where a user can enter a URL, and our server-side code will take that URL and return its content. This operation is done using the curl command as follows:
$url = $_GET["url"]; // acquire the URL
echo shell_exec("curl $url"); // execute the command and print its output
For example, the user enters https://example.com and submits the form, and the following result is shown on the screen:
Until now, everything looks fine. However, let's assume the worse: a user tries and enters (https://example.com/ && sleep 100). In this case, the OS shell will execute the following command:
curl https://example.com && sleep 100
This command will retrieve the content of the URL and then pause for 100 seconds. PHP will wait until shell_exec() returns before resuming execution. Until now, there's nothing much serious happening here. However, let's assume that our user used an input like (https://example.com/ && rm -rf app). In this case, the OS shell will run the following command:
curl https://example.com && rm -rf app
Essentially, this command performs two actions: firstly, it retrieves the contents of a URL, and secondly, it deletes the "app" folder in the current directory. The second action has the potential to cause severe damage to the system and should be avoided.
What Should Be Done About This?
There are several methods that can be effective in reducing the likelihood of such attacks. Let's explore some of these methods.
Don't Call OS Commands Directly
The primary cause of an application's vulnerability to command-line injection is the unsafe practice of directly concatenating parameters with the command, making it risky to execute. To prevent this vulnerability and avoid potential headaches, it is advisable to utilize built-in functions that can perform the same task instead of writing such commands directly.
For example, in PHP:
And so on. Almost every command has an equivalent function in PHP that encapsulates it. These functions work in a safe way that prevents changing the intent of the command.
Escape Values Passed To The Command
If you cannot find a function that encapsulates the desired command, and you don't have any solutions left, you still can do it in a safe way.
领英推荐
Thank God, in PHP we have a function called escapeshellarg(). This function takes the input and escapes it in a safe manner that makes the command less dangerous to execute. For example:
$url = $_GET["url"]; // acquire the URL
$clean_url = escapeshellarg($url); // sanitize the URL
echo shell_exec("curl $clean_url");
Now, if the user enters (https://example.com/ && rm -rf test-folder) as a URL, then the escape function will escape it, and the final command to be executed will look like this:
curl 'https://example.com/ && rm -rf test-folder'
And curl will reply with an error regarding the format of the URL. As you can see, the whole user input part has been interpreted as a parameter to be passed to the command.
Input Validation & Whitelisting
Regarding the arguments of command, there should be a whitelisting policy such that the arguments and their corresponding values are explicitly defined or validated using a regular expression approach such that:
This topic will get the focus it deserves in a future article.
The Concept Of Least Privilege
Each process runs on behalf of a specific user and has its own set of privileges. For example, the www-data or nginx users which are used by several types of web servers may not need to have access to files inside the directory /usr/local/bin, and they also may not need to have access that allows them to control system services.
Instead, a process should get the minimum required amount of privileges to run correctly. Don't give more privileges than needed to a process.
Laravel And Command Line Injection
Luckily, Laravel framework provides the Process facade which is a wrapper around the process component in Symfony. The facade is available under the Illuminate\Support\Facades namespace.
This addition is very powerful, it provides many options to control the execution of a process plus the ability to run asynchronous and run processes. However, what matters for us here is the run() method. This method takes a single parameter which can be either a string or an array.
Let's see our curl example once again written using this feature:
use Illuminate\Support\Facades\Process;
$url = $request->url;
$process = Process::run(["curl", $url]);
$process->output();
$process->errorOutput();
If the URL passed was invalid or malformed, curl will reply with the same error message we have previously seen.
Conclusion
In conclusion, command line injection is a serious security vulnerability that can allow attackers to execute arbitrary commands on a system. It can be prevented by properly validating and sanitizing all user input that is passed to a?command line interpreter, and by using safer alternatives to executing commands whenever possible. If you suspect that your system may be vulnerable to?command line injection, it is important to take immediate action to mitigate the risk and implement additional security measures to prevent similar vulnerabilities from occurring in the future. By following best practices for?secure coding?and regularly updating and monitoring your system, you can help protect yourself and your users from the risks of command line injection and other security threats.
Software Enginer
1 年I love your articles it always has something new to learn from.