Skip to main content

6065 - Commandline arguments injection

TL;DR#

This category indicates that user-controlled input flows into a command-line argument used to execute an external process. Unlike category 5001, this leads to a Remote Code Execution issue only in specific cases (e.g., shell=True parameter or when executing particular binaries).

ISSUE#

subprocess.Popen, subprocess.run, subprocess.call, and other functions do a good job in preventing by default the command injection issues we described in category 5001. The values supplied in the args parameter (excluding the first which represents the executable) are considered only as arguments and not as commands to be interpreted in a system shell (more details in the python documentation). However, this safe behaviour can be manually bypassed by specifying the shell=True parameter, which reintroduces the command injection issue.

EXAMPLE#

The following code is intended to run the spellcheck binary on a user provided text:

def spellcheck(request: HttpRequest):
command = "/usr/bin/spellcheck -l {}".format(request.GET['text'])
return subprocess.run(command, shell=True)

An attacker, however, can supply a path such as 'test' && rm -rf /, which would result in the following command being executed: /usr/bin/spellcheck -l 'test' && rm -rf /. Since this command is executed in a system shell the rm -rf / command will be executed after the spellcheck command.

RECOMMENDED SOLUTION#

In general, we recommend avoiding creation of a subprocess and prefer using the API provided by the language. However, if you need to create a subprocess, we recommend using a safe API such as subprocess.run and avoiding use of the shell=True argument. If this is not possible, we recommend ensuring that the user-controlled values are shell-escaped with shlex.quote.

def spellcheck(request: HttpRequest):
command = ["/usr/bin/spellcheck", "-l", request.GET['text']]
subprocess.run(command)

NOTE: be conscious of the fact that arguments to an executable can still lead to code execution (e.g., the -exec argument of find).