Overview
Command Injection (or OS Command Injection) allows an attacker to execute arbitrary commands on the host operating system via a vulnerable application. This flaw occurs when an application passes unsanitized user-supplied data to a system shell. By injecting command separators like;, &&, or |, an attacker can append their own commands to the legitimate one, which are then executed with the privileges of the application.
Business Impact
This is one of the most critical vulnerabilities, as it can lead to a full compromise of the application server. An attacker can read/write any file, install malware or ransomware, exfiltrate all data, and use the compromised server as a pivot point to attack the internal network.Reference Details
CWE ID: CWE-78
OWASP Top 10 (2021): A03:2021 - Injection
Severity: Critical
Framework-Specific Analysis and Remediation
The only truly safe way to prevent command injection is to avoid calling out to OS commands with user-supplied data. Almost every language provides safe, built-in libraries for functionality that developers might otherwise try to achieve via shell commands (e.g., file operations, network requests). If executing a command is absolutely unavoidable, the application must use APIs that execute processes directly without invoking a shell, passing each user-controlled input as a separate, distinct argument.- Python
- Java
- .NET(C#)
- PHP
- Node.js
- Ruby
Framework Context
Python’s standardos.system() function is a direct conduit to the system shell and is extremely dangerous. The subprocess module is the modern, secure alternative, but it can still be made vulnerable if shell=True is used with untrusted input.Vulnerable Scenario 1: A Video Conversion Service
A service uses theffmpeg command-line tool to convert uploaded video files, taking conversion options from the user.Vulnerable Scenario 2: Network Diagnostic Tool
An admin panel includes a tool to ping a user-supplied IP address.Mitigation and Best Practices
Use thesubprocess module and pass the command and its arguments as a list of strings (e.g., ['ping', '-c', '4', host]). This invokes the program directly without a shell, ensuring that the user’s input is treated as a single, safe argument and cannot be interpreted by the shell.Secure Code Example
Testing Strategy
Write tests that pass payloads containing shell metacharacters as input. For the ping example, a payload could be8.8.8.8; ls. The test should assert that the command output does not contain the results of the injected ls command and that the program likely exited with an error because “8.8.8.8; ls” is not a valid hostname.
