A trap of shell=True in the subprocess module
If you look into a page of a subprocess module you find a few red boxes warning you that
shell=Trueis insecure. Malicious user may use
shfeatures to execute unexpected code and so on.
At the same page you will find another remark, less visual, but in my opinion, much more important:
On Unix with
shell=True… If args is a string, the string specifies the command to execute through the shell … If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself.
One may even didn’t notice such a huge change at a first glance.
Let’s look on this example:
>>> subprocess.call([‘id’, ‘root’])
uid=0(root) gid=0(root) groups=0(root)
>>> subprocess.call(['id', 'root'], shell=True)
uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),25(floppy), ...
You may be amused by this. Without quotation above it’s almost impossible to figure out what had happened.
When you add
shell=True, and pass command line arguments as a list, only first element of the list will be executed. Rest will be ignored or would change
sh behavior if it contains valid shell arguments.
Basically, when you add
shell=True it completely changes interpretation for command line:
args[:]is a command line to execute
argsis a command line to execute and
args[1:]is arguments to
(I repeated this idea twice, because I still can’t believe anyone would design such a grotesque interface for the standard library of commonly-used language…)