← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Command Injection

security CWE-78 OWASP A3:2021 CVSS 9.8 PHP 5.0+ Intermediate

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

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);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 32
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 1 ping S 1 ping M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T
No pings yet today
Perplexity 8 Amazonbot 6 Ahrefs 4 Unknown AI 3 Google 2 ChatGPT 2
crawler 24 crawler_json 1
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
🔗 Prerequisites
🔍 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

✓ schema.org compliant