01Summary

This weakness occurs when a program allows external input (from a user, network request, file, or environment) to directly influence which process is executed, what arguments it receives, or where it loads from. An attacker can exploit this to run arbitrary code or unintended programs with the privileges of the vulnerable application.

02How It Happens

The vulnerability arises when developers construct process names, file paths, or command-line arguments by concatenating or interpolating untrusted input without validation or sanitization. Common scenarios include:

- Building a command string from user input and passing it to a shell interpreter - Using user-supplied data to determine which executable to run - Allowing input to modify environment variables or library search paths that affect process loading - Constructing arguments to a subprocess without proper escaping or allowlisting

The root cause is treating external input as trusted code or configuration rather than data that must be validated and constrained.

03Real-World Impact

Successful exploitation allows an attacker to execute arbitrary code with the same privileges as the vulnerable application. This can lead to complete system compromise, data theft, malware installation, lateral movement to other systems, or denial of service. The severity depends on the application's privilege level and network exposure.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import subprocess
import sys

user_command = sys.argv[1]
# Directly using user input to construct a shell command
result = subprocess.run(user_command, shell=True, capture_output=True)
print(result.stdout.decode())

Why it's vulnerable:
The shell=True parameter interprets the user input as shell syntax, allowing injection of arbitrary commands. An attacker can append ; malicious_command or use other shell metacharacters to execute unintended code.

Fixed pattern
import subprocess
import sys

user_command = sys.argv[1]
# Use a list of arguments and avoid shell interpretation
allowed_commands = ["list_files", "show_status", "check_health"]
if user_command not in allowed_commands:
    raise ValueError("Invalid command")
result = subprocess.run(["/usr/bin/myapp", user_command], capture_output=True)
print(result.stdout.decode())
Vulnerable pattern
<?php
$filename = $_GET['file'];
// Directly using user input in a system command
$output = shell_exec("cat " . $filename);
echo $output;
?>

Why it's vulnerable:
The filename is concatenated directly into the shell command without escaping. An attacker can supply file.txt; rm -rf / or use other shell metacharacters to execute arbitrary commands.

Fixed pattern
<?php
$filename = $_GET['file'];
// Validate against an allowlist of permitted files
$allowed_files = ['report.txt', 'summary.txt', 'log.txt'];
if (!in_array($filename, $allowed_files, true)) {
    die('Invalid file');
}
// Use escapeshellarg() if shell execution is necessary
$safe_filename = escapeshellarg($filename);
$output = shell_exec("cat " . $safe_filename);
echo $output;
?>

05Prevention Checklist

Avoid shell interpretation:
Use parameterized process execution (e.g., subprocess.run() with a list, not shell=True) whenever possible.
Allowlist permitted commands and arguments:
If user input must influence process execution, restrict it to a predefined set of safe values.
Validate and escape input:
If shell execution is unavoidable, use language-specific escaping functions (escapeshellarg() in PHP, shlex.quote() in Python).
Run with minimal privileges:
Execute processes with the lowest privilege level necessary; avoid running as root or administrator.
Use absolute paths:
Specify the full path to executables rather than relying on PATH environment variable resolution.
Audit subprocess calls:
Regularly review code that invokes external processes and ensure no user input flows into command construction.

06Signs You May Already Be Affected

Look for unexpected processes spawned by your application, unusual system calls in logs, or evidence of files being created or modified outside normal operation. Check for suspicious entries in process audit logs or system call traces that correlate with user requests. If your application has ever crashed with a shell error or returned unexpected output, investigate whether input validation was bypassed.

07Related Recent Vulnerabilities