Command injection is a common security vulnerability. Injection attacks are #1 on the OWASP Top Ten List of globally recognized web application security risks, with command injection being one of the most popular types of injections.
What is OS command injection?
A command injection vulnerability allows attackers to execute arbitrary system commands on the attacked party’s host operating system (OS). Doing this can override the original command to gain access to a system, obtain sensitive data, or even execute an entire takeover of the application server or system.
Some typical examples of command injection attacks include the insertion of harmful files into the runtime environment of the vulnerable application’s server, shell command execution, and abuse of configuration file vulnerabilities.
The basics of command injection vulnerabilities
A command injection attack can occur with web applications that run OS commands to interact with the host and file systems. They execute system commands, start applications in a different language, or execute shell, Python, Perl, or PHP scripts. While this functionality is standard, it can be used for cyber attacks.
The main loophole through which command injection can be executed is when user-supplied input is not validated in applications. This input is used in the construction of commands that will be executed. Such cyber-attacks are possible when a web application passes the unverified user input (cookies, forms, HTTP headers, and the like) directly to OS functions like exec() and system(). The input is always a string (string cmd) linked to a constant string of the application, which shapes the full command.
Command injection is also known as shell injection. The arbitrary commands that the attacker applies to the system shell of the webserver running the application can compromise all relevant data. The command injection can also attack other systems in the infrastructure connected to and trusted by the initial one. This is how the attacker can use the privileges of the targeted application to gain wider control over the system.
Most OS command injections are blind security risks. The targeted application doesn’t return the command output within the HTTP response. Still, blind injections are a security threat and can be used to compromise a system.
Command injection security assessment level
The differences between command injection and code injection
While they seem similar, code and command injection are different types of vulnerabilities.
Code injection entails an attacker inserting new malicious code into a vulnerable application, which executes. The attack is based on insufficient input validation of the malicious version of user data. Therefore, the code injection attack is limited to the functionalities of the application that is being targeted.
In contrast, a command injection is a case when an attacker modifies the default function of the application that executes system commands. Thus, no new code is being inserted. However, with a command injection, an attacker can target the server or systems of the application and other trusted infrastructure by using the compromised application’s privileges.
Methods for command injection
A command injection attack can happen due to various types of vulnerabilities.
Here are some common ones:
- Arbitrary command injections: applications that allow a malicious user to run arbitrary commands can be attacked in this way
- Insecure deserialization: executing deserialization without performing proper input validation can lead to command injections
- XML external entity injection (XXE): if an application uses an XML parser that hasn’t been configured properly to parse user XML input, this can lead to Denial of Service (DoS) attacks, Server-Side Request Forgery (SSRF), and breaches to vulnerable data
- Arbitrary file inclusion/upload: applications that allow users to upload files with arbitrary files extensions can be vulnerable to command injections through malicious commands when inserting into the webroot
- Server-side template injection (SSTI): applications that use server-side templates to generate dynamic HTML responses may be vulnerable to the insertion of harmful server-side templates if unsafe user-supplied data is included in a template
Examples of command injection
Malicious attackers can escape the ping command by adding a semicolon and executing arbitrary attacker-supplied operating system commands.
<?php $ip = $_POST['ip']; $cmd = system('ping '.$ip); echo $cmd ?> Example input: ; cat /etc/passwd
To ensure your web application is not vulnerable to command injections, you’ll have to validate all user input and only allow commands needed for the task. You can also clean up user input by removing special characters like ; (semi-colon), and other shell escapes like &, &&, |, ||, <.
How you can detect OS command injection attacks
There are many ways to detect command injection attacks. One way is to look at the request parameters and see whether there are any suspicious strings. Another method is to examine the response body and see whether there are unexpected results.
If you find that some of your application’s parameters have been modified, it could mean someone has performed a command injection attack against your application.
How to prevent command injection
There are proven ways to limit the situations in which command injections can be executed in your systems.
Here are the most useful tips for applying:
- Limit the use of shell command execution functions as much as possible
- Employ a trusted API for user input into your application, especially when running system commands such as execFile()
- Always validate user input that will be feeding into a shell execution command, which entails having a sound input validation strategy
- Filter potentially problematic special characters by using an allowlist for user input or by targeting command-related terms and delimiters
- Encode user input before using it in commands to avoid command-related characters being read as elements of the command or as a delimiter, as well as malformed inputs
- Parameterize user input or limit it to certain data sections of the command to avoid the input being read as an element of the command
- Make sure users can’t get control over the name of an application by using execFile() securely
A command injection vulnerability exists when user-supplied input is not validated correctly by the web application. The following snippet shows PHP code that is vulnerable to command injection.
How do I protect myself from these attacks?
Following the above guidelines is the best way to defend yourself against command injection attacks. However, suppose you prefer to use automated pentesting rather than a manual effort to test for dangerous software weaknesses. In that case, you can use a dynamic application security testing tool to check your applications.
You can quickly try out Crashtest Security’s Vulnerability Testing Software to spot command injection risks and prevent potential attacks.
Testing for command injection vulnerabilities
Application security is a top priority, so it’s important to check your systems’ critical vulnerability risks regularly.
To check for blind command injections, you can use various detection techniques, such as time delays, redirecting output and checking the file manually, or running an OOB network interaction with an external server.
You can use some common parameters to test for operating system command injections:
Command Injection Video Explanation
Frequently Asked Questions
What is the difference between SQL injection and command injection?
SQL injection is an attack where malicious code is injected into a database query. It allows attackers to read, write, delete, update, or modify information stored in a database.
In contrast, command injection exploits vulnerabilities in programs that allow the execution of external commands on the server. As a result, attackers can inject their commands into the program, allowing them to take complete control of the server.
How can I fix my existing code so it won’t be vulnerable to these attacks?
To avoid command injection attacks, you need to validate every parameter passed to your application. Ensure that the application correctly validates all parameters.
For instance, if you’re building a login page, you should first check whether the username provided by the user is valid. Then, you should ensure the user’s password is strong enough. Finally, you should check whether this combination exists in the database.
If you’re receiving data from a third-party source, you should use a library to filter the data. For instance, if the data comes from a web service, you can use the OWASP Web Services Security Project API, which provides methods for filtering input data based on various criteria.
Also, if you’re receiving data from another application, you should use the same techniques when sending data to another application.