Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Shell=True for Python subprocess module [duplicate]

It seems whenever I try to use Python's subprocess module, I find I still don't understand some things. Currently, I was trying to join 3 mp4 files from within a Python module.

When I tried

z ='MP4Box -cat test_0.mp4 -cat test_1.mp4 -cat test_2.mp4 -new test_012d.mp4'
subprocess.Popen(z,shell=True)

Everything worked.

When I tried

z = ['MP4Box', '-cat test_0.mp4', '-cat test_1.mp4', '-cat test_2.mp4', '-new test_012d.mp4']
subprocess.Popen(z,shell=False)

I got the following error:

Option -cat test_0.mp4 unknown. Please check usage

I thought that for shell=False I just needed to supply a list where the first element was the executable I wanted to run and each succeeding element was an argument to that executable. Am I mistaken in this belief, or is there a correct way to create the command I wanted to use?

Also, are there any rules for using Shell=True in subprocess.Popen? So far, all I really know(?) is "don't do it - you can expose your code to Shell injection attacks". Why does Shell=False avoid this problem? Is there ever an actual advantage to using 'Shell=True`?

like image 511
user1245262 Avatar asked Jun 14 '15 14:06

user1245262


People also ask

Should I use shell true in subprocess?

We should avoid using 'shell=true' in subprocess call to avoid shell injection vulnerabilities. In this call you have to pass a string as a command to the shell. If call_method is user controlled then it can be used to execute any arbitrary command which can affect system.

Why are shells true in subprocess?

Setting the shell argument to a true value causes subprocess to spawn an intermediate shell process, and tell it to run the command. In other words, using an intermediate shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run.

How can we avoid shell true in subprocess?

From the docs: args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).

What does Popen shell do?

The popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read- only or write-only.


1 Answers

If shell is True, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user’s home directory.

When shell=True is dangerous?

If we execute shell commands that might include unsanitized input from an untrusted source, it will make a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True is strongly discouraged in cases where the command string is constructed from external input

Eg. (Taken from docs)

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly..
like image 154
Rahul Gupta Avatar answered Sep 22 '22 08:09

Rahul Gupta