Command Injection

Back to glossary

What Is Command Injection?

Command injection is a vulnerability that allows an attacker to execute arbitrary operating system commands on a server by manipulating application input. It occurs when an application passes user-controlled data directly to a system shell without proper validation or sanitization.

A command injection attack can be devastating. Successful exploitation gives the attacker the same privileges as the application process, which often runs with elevated permissions. From there, they can read sensitive files, install malware, pivot to other systems, or take full control of the host. Command injection has remained a persistent threat for decades because it exploits a fundamental flaw: trusting user input.

How Command Injection Attacks Work

The mechanics of a command injection vulnerability are straightforward. An application constructs an operating system command using input from the user, then passes that command to a system shell for execution. If the input is not sanitized, the attacker appends additional commands using shell metacharacters.

Consider an application that lets users check the status of a server by hostname:

system(“ping -c 4 ” + userInput)

A legitimate user enters example.com, and the application executes ping -c 4 example.com. An attacker enters example.com; cat /etc/passwd, and the application executes both commands: the ping and the password file read.

Shell Metacharacters Used in Command Injection

CharacterFunctionExample
;Command separatorinput; malicious_command
&&Execute second command if first succeedsinput && malicious_command
||Execute second command if first failsinput || malicious_command
Command substitution (backticks)input malicious_command`
$()Command substitutioninput $(malicious_command)
|Pipe output to another commandinput | malicious_command

Operating system command injection can also occur indirectly. Instead of injecting into a direct shell call, attackers may manipulate environment variables, file paths, or configuration values that are later used in shell commands by other parts of the application.

Application layer attacks like command injection exploit the trust an application places in its input. Unlike network-layer attacks that target infrastructure, these vulnerabilities exist in the application logic itself and must be addressed in code.

Common Command Injection Vulnerability Scenarios

Command injection appears wherever applications interact with the operating system through shell commands. Some scenarios are more common than others.

File Operations

Applications that process uploaded files often use system commands for conversion, compression, or metadata extraction. If the filename or file path is user-controlled and passed to a shell command, injection is possible.

Network Utilities

Web applications that expose diagnostic tools (ping, traceroute, DNS lookup, whois) frequently construct shell commands from user input. These are among the most commonly exploited command execution vectors.

PDF and Image Processing

Backend tools like ImageMagick, Ghostscript, and FFmpeg are frequently invoked through shell commands. User-supplied filenames, URLs, or processing parameters that reach these commands without sanitization create injection opportunities.

CI/CD Pipelines

Build scripts and automation pipelines that construct shell commands using variables from pull requests, commit messages, or configuration files can be exploited if those inputs are attacker-controlled. This represents a growing risk area as organizations adopt complex OWASP-aligned practices for cloud-native applications.

Server Management Interfaces

Admin panels that execute system commands (restarting services, managing users, viewing logs) based on form input are high-value targets. If accessible to attackers through authentication bypass or privilege escalation, they provide direct command execution.

Preventing Command Injection in Modern Applications

Preventing command injection requires eliminating the root cause: constructing shell commands from user input. When that is not possible, multiple layers of defense reduce the risk.

Avoid Shell Commands Entirely

The most effective prevention is never passing user input to a system shell. Most operations that developers implement through shell commands have native library equivalents:

  • File operations: Use language-native file I/O libraries instead of calling cp, mv, or rm through a shell.
  • Network operations: Use socket libraries or HTTP clients instead of calling ping, curl, or wget.
  • Process management: Use process spawning APIs that accept argument arrays (bypassing shell interpretation) instead of constructing command strings.

Input Validation and Sanitization

When shell interaction is unavoidable:

  • Allowlist validation: Restrict input to known-safe patterns (alphanumeric characters, specific domains, predefined options). Reject anything that does not match.
  • Escape shell metacharacters: Use language-specific escaping functions (shlex.quote() in Python, escapeshellarg() in PHP) to neutralize special characters.
  • Parameterized execution: Use APIs that pass arguments as separate parameters rather than concatenating them into a command string (e.g., subprocess.run() with a list argument in Python).

Defense in Depth

Even with strong input handling, additional layers limit the damage if a command injection succeeds:

  • Least privilege: Run application processes with the minimum OS permissions necessary. If the process cannot read /etc/shadow or write to system directories, a successful injection causes less damage.
  • Sandboxing and containers: Isolate application processes in containers or sandboxes that limit system call access and filesystem visibility.
  • Web application firewalls (WAFs): WAFs can detect and block common command injection patterns in HTTP requests, though they should not be relied on as the sole defense.

Embedding input validation practices and secure coding patterns from the design phase forward, following secure software design best practices, prevents command injection from entering the codebase in the first place.

FAQs

How does command injection differ from SQL injection attacks?

Command injection targets the operating system shell, executing OS-level commands. SQL injection targets database query interpreters. Both exploit unsanitized user input but attack different system layers.

Why are command injection vulnerabilities still common today?

Developers still construct shell commands from user input for convenience, especially in scripting languages. Legacy code, rapid prototyping, and insufficient security training perpetuate the pattern across modern applications.

What role does input validation play in preventing command injection?

Input validation is the primary defense. Allowlisting acceptable characters and patterns, escaping metacharacters, and using parameterized execution APIs prevent attacker-controlled data from being interpreted as shell commands.

How does command injection impact containerized or cloud workloads?

In containerized environments, successful command injection can lead to container escape if the container runs with excessive privileges. In cloud workloads, it can expose metadata services, credentials, and adjacent resources.

Can runtime security controls help detect command injection attempts?

Yes. Runtime application self-protection (RASP), system call monitoring, and anomaly detection can identify unexpected shell command execution patterns and block or alert on suspicious activity.

Back to glossary
See Apiiro in action
Meet with our team of application security experts and learn how Apiiro is transforming the way modern applications and software supply chains are secured. Supporting the world’s brightest application security and development teams: