liveBook · Manning

Command injection

As explained in Grokking Web Application Security

Command injection is an attack in which crafted input causes an application to execute unintended commands on the operating system.

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

Language

Recommendation

Python

The subprocess package allows you to pass individual command arguments to the run() function as a list, which protects you from command injection:

from subprocess import run
run(["ns_lookup", domain])

Ruby

Use the shellwords module to escape control characters in command strings:

require 'shellwords'
Kernel.open("nslookup #{Shellwords.escape(domain)}") 

Node.js

The child_process package allows you to pass individual command arguments to the spawn() function as an array, which protects you from command injection:

const child_process = require('child_process')
child_process.spawn('nslookup', [domain])

Java

The java.lang.Runtime class allows you to pass individual command arguments to the exec() function as a String array, which protects you from command injection:

String[] command = { "nslookup", domain };
Runtime.getRuntime().exec(command);

.NET

Use the ProcessStartInfo class from the System.Diagnostics namespace to allow structured creation of command-line calls:

var process = new ProcessStartInfo()
process.UseShellExecute = true;
process.FileName  = @"C:\Windows\System32\cmd.exe";
process.Verb      = "nslookup";
process.Arguments = domain;
Process.Start(process);

PHP

Use the built-in escapeshellcmd() function to remove control characters before running command-line calls:

$domain  = $_GET['domain']
$escaped = escapeshellcmd($domain);
$lookup  = system("nslookup {$domain}");

Compare argument-handling or escaping recommendations for Python, Ruby, Node.js, and Java. section 12.13

How Grokking Web Application Security covers it

How deep it goes
Demonstrates attack mechanics, consequences, and prevention through command chaining and language-specific invocation patterns.
Examples
Uses Python subprocess and os examples, an nslookup site, and the Linux payload `file.txt && rm -rf /`.
What it assumes
Assumes familiarity with application input and operating-system commands while explaining command chaining and unsafe construction directly.
What you can do after
Apply safer command execution by avoiding direct system calls, separating arguments, or escaping and sanitizing necessary inputs.
How it connects
Connects command injection with input sanitization, character escaping, shell commands, web applications, and operating-system APIs.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Web Application Security. The section links point to the parts of the book it draws on.