Command Injection
Last updated
Last updated
Command injection (or OS command injection) is an attack in which the goal is the execution of arbitrary OS commands. Command injection attacks are possible when an application passes user-controlled data directly to the shell, allowing an attacker to inject and execute arbitrary commands.
For example, in the snippet below, if an attacker can control the ip
variable, they will be able to execute arbitrary commands by passing the 1.1.1.1; id
value to ip
variable.
You can find more details at PortSwigger Web Security Academy: OS command injection.
This page contains recommendations for the implementation of protection against command injection attacks.
Do not call OS commands directly if there is a library or API for your language.
Use parameterized methods that allow automatically applying a separation between data and command, see the Parameterized command execution implementation section.
Usually parameterized methods take a list as input (a command name and its arguments), not a string. So, if a method accepts a string, this method is most likely vulnerable to command injection.
If it is not possible to use APIs or parameterized methods, you can use environment variables to pass user-controlled data.
Do not use user-controlled data as a name when setting environment variables. Instead, generate random names.
Implement comprehensive input validation, see the Input Validation page.
Define an allow list of commands.
Define an allow list of arguments.
Define an allow list of characters (alphanumeric characters only) to validate commands, arguments and operands.
Define an allow list of environment variable names.
Define an allow list of environment variable values.
Do not use block list validation.
Do not run commands inside of a shell.
Do not pass a shell to a parameterized method as a command. For example, the following snippet is vulnerable to command injection:
Do not enable running commands inside of a shell using an argument like the "shell" in child_process.Spawn in Node.js:
Use --
to separate operands from arguments.
Be aware that methods not directly related to executing OS commands can execute OS commands under the hood and be vulnerable to command injection.
Use a sandbox to execute OS commands.
Use the os/exec package to execute OS commands.