Command Injection
Also Known As
OS command injection
shell injection
RCE via shell
TL;DR
User input passed to a shell function (exec, system, shell_exec) allows arbitrary OS command execution.
Explanation
Command injection occurs when user-controlled data is incorporated into a shell command without sanitisation. Attackers can append additional commands using shell metacharacters (;, |, &&) to run arbitrary programs with the web server's privileges — reading files, exfiltrating data, installing backdoors, or pivoting to other systems. Prevention: avoid shell functions entirely where possible; if unavoidable, use escapeshellarg() on every argument and escapeshellcmd() on the command.
How It's Exploited
POST filename=image.jpg; rm -rf /var/www
# Deletes your web root
# Deletes your web root
Diagram
flowchart TD
USER_CMD[User input: filename] --> CONCAT2[exec ls -la . filename .]
CONCAT2 -->|input: . ; rm -rf /| EXEC2[Shell executes:<br/>ls -la .<br/>rm -rf /]
EXEC2 --> DISASTER[Files deleted!]
subgraph Fix
ESCAPE[escapeshellarg wraps in quotes<br/>escapes all shell metacharacters]
VALIDATE[Allowlist valid inputs<br/>reject anything else]
AVOID[Use PHP functions directly<br/>avoid shell when possible]
end
style CONCAT2 fill:#f85149,color:#fff
style DISASTER fill:#f85149,color:#fff
style ESCAPE fill:#238636,color:#fff
Common Misconception
✗ escapeshellarg() makes all shell calls safe. It secures arguments but does nothing if user input appears in the command name itself. The safest approach is proc_open() with an array, which bypasses the shell entirely.
Why It Matters
Any user input reaching shell execution functions can run arbitrary OS commands with the web server's privileges — full server compromise from a single unvalidated parameter.
Common Mistakes
- Using shell_exec(), system(), or exec() with unsanitised user input even after escapeshellarg().
- Passing user-controlled arguments where escapeshellarg() is applied to the whole string but injection happens via argument structure.
- Using PHP functions that invoke a shell implicitly — preg_replace with /e modifier (removed in PHP 7), or older mail() with fifth argument.
- Not considering that command injection can occur in less obvious places like image processing CLI calls.
Code Examples
✗ Vulnerable
$file = $_POST['filename'];
exec("convert $file output.pdf");
✓ Fixed
// escapeshellarg wraps in single quotes and escapes embedded quotes
$file = escapeshellarg($_POST['filename']);
exec('convert ' . $file . ' output.pdf');
// Better: avoid shell entirely — use proc_open with an array
proc_open(['convert', $file, 'output.pdf'], $descriptors, $pipes);
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
32
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Perplexity 8
Amazonbot 6
Ahrefs 4
Unknown AI 3
Google 2
ChatGPT 2
Also referenced
How they use it
crawler 24
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: Low
⚡ Quick Fix
Use escapeshellarg() on every argument passed to shell_exec/exec; prefer PHP-native functions over shell commands entirely
📦 Applies To
PHP 5.0+
web
cli
🔍 Detection Hints
shell_exec( or exec( or system( or passthru( or backtick with variable interpolation
Auto-detectable:
✓ Yes
semgrep
phpstan
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✗ Manual fix
Fix: High
Context: Function
Tests: Update
CWE-78
CWE-88