Command injection: when a parameter runs a shell command

Passing request input to a shell lets the caller end your command and start their own. One semicolon is enough.

Example

Vulnerable
const { exec } = require("child_process");

app.get("/ping", (req, res) => {
  exec("ping -c 1 " + req.query.host, (err, out) => res.send(out));
});
Fixed
const { execFile } = require("child_process");
const HOST = /^[a-z0-9.-]{1,253}$/i;

app.get("/ping", (req, res) => {
  const host = String(req.query.host);
  if (!HOST.test(host)) return res.sendStatus(400);
  execFile("ping", ["-c", "1", host], (err, out) => res.send(out));
});

How it happens

Functions such as exec, execSync, os.system or subprocess with shell=True hand the whole string to /bin/sh, which interprets ;, &&, |, backticks and $( ). A host parameter of example.com; cat /etc/passwd runs both commands with the server's permissions — reading secrets, installing malware, moving to other machines.

How to fix it

Do not involve a shell at all.

  • Use execFile or spawn with an argument array (subprocess.run([...]) in Python) and no shell option
  • Validate the value against an allowlist pattern before using it
  • Prefer a library call over shelling out to a tool when one exists

How RepoVerse finds it

  • CriticalRequest input reaches a shell command

    A `;` or `$(…)` in the input runs a second command on the host.

    data flow · CWE-78

  • HighShell command built from a variable

    A command string is interpolated and then executed.

    pattern

  • HighSubprocess run through a shell

    `shell=True` hands the command line to `/bin/sh`, so a semicolon or backtick in any interpolated value runs a second command.

    pattern

Questions

Is spawn safe from command injection?
spawn and execFile with an argument array do not start a shell, so metacharacters are not interpreted. Passing shell: true brings the risk back.
How does RepoVerse find command injection?
It traces request input to child_process calls and shell helpers and reports the path; line rules also flag shell=True in Python and string-built commands in other languages.

Related

Updated 2026-10-11