Command injection
Untrusted text gets pasted into a shell command, letting an attacker turn a filename or form value into commands your server runs.
See it
What it is
Command injection happens when an application puts untrusted text inside a shell command. Shell metacharacters such as semicolons, pipes, and command substitution can end the intended argument and start a new command with the application's operating-system permissions. A harmless image filename can become code if it is pasted into a string sent to bash. Shellshock (CVE-2014-6271) was the mass-scale version: bash kept executing whatever trailed a crafted environment variable, so any CGI script that shelled out handed the machine over.
The durable move is to avoid a shell. Call the needed library directly, or launch one fixed executable with a separate argument array. In Node.js, child_process.execFile and spawn with shell: false preserve the boundary between the program and its data. Validate arguments against the narrow shape the operation expects as a second layer, not as the primary fix.
The trap is reaching for escaping or a blocklist. Shell parsing varies across Bash, cmd.exe, and PowerShell, and there is always another special form to miss. Another trap is argument injection: even without a shell, user text beginning with a dash may be interpreted as an option by the target program. Use an API, allowlist values, or the program's end-of-options marker where it supports one.
Ask AI for it
Remove command injection from this Node.js codebase. Find every use of child_process.exec, execSync, shell: true, and string-built subprocess command. Replace each with a direct library API where one exists; otherwise use child_process.execFile or spawn with shell: false, a hardcoded executable, and a separate argument array. Validate every untrusted argument with a zod allowlist or strict format, reject leading option markers where the target program could parse them, and never add quote escaping as the fix. Add regression tests with semicolons, pipes, command substitution, newlines, spaces, and leading dashes, asserting they are rejected or passed as one literal argument and no marker file is created.