Command injection occurs when crafted input makes an application execute unintended operations on the operating system. It usually begins when untrusted data is inserted directly into a command-line string. section 4.11 section 12.13
A chained command
A site that performs DNS lookups might append a URL parameter to an nslookup command. An attacker can add the Linux && operator, chaining another command to the intended lookup. Similarly, inserting `file.txt && rm -rf /` after `cat` can read the requested file and then delete files on the server. The impact can include sensitive-file disclosure, malware installation, ransomware, or attacks against other servers. section 4.11 section 12.13
Reduce the attack surface with these practical choices:
- Avoid invoking the operating system directly when a higher-level API can perform the task, such as using Python's os functions for file access. section 4.11 section 12.13
- If a command is necessary, pass separate arguments rather than concatenating untrusted input into a command string; Python's subprocess, Node.js child_process, and Java Runtime examples use argument arrays. section 12.13
- If constructing a command string yourself, escape control characters and sanitize inputs; escaping is complicated because control characters differ between Windows and UNIX-based systems. section 4.11 section 12.13
from subprocess import run
response = run("cat " + input_value, shell=True)
Inspect the vulnerable Python pattern that concatenates input into a shell command. section 4.11
cat file.txt && rm -rf /
Inspect the injected Linux command chain and its destructive second operation. section 4.11
from subprocess import run response = run(["cat", input_value], shell=False)
Compare the safer Python form that supplies the command and input as separate arguments. section 4.11
Compare argument-handling or escaping recommendations for Python, Ruby, Node.js, and Java. section 12.13
