Command injection

Untrusted text gets pasted into a shell command, letting an attacker turn a filename or form value into commands your server runs.

user input ran a shell commandsemicolon in the form executed somethingthe server passed text into bashshell injectionOS command injectioncomand injectionfilename made the server run a commandmy ffmpeg call takes the filename straight from the uploadis it safe to build a terminal command out of user text

See it

Live demo coming soon

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.

You might have meant

sql injectioninput validation and contextual output encodingssrfleast privilegedefense in depth

Go deeper