Basically which python's functions trigger bash (and might be impacted by shellshock), and which don't ?
I have come up with this question by seeing in some scripts the popen()
function.
My question relates to both Python 2 and 3.
Basically which python's functions trigger bash (and might be impacted by shellshock), and which don't ?
I have come up with this question by seeing in some scripts the popen()
function.
My question relates to both Python 2 and 3.
Any program that, at some point, calls bash
is affected. In particular the os.system
function is vulnerable if the system has bash
as /bin/sh
, so any program calling it (or some equivalent) is vulnerable too.
The popen
functions can be vulnerable, depending on the arguments passed. Quoting from the documentation:
Also, for each of these variants, on Unix,
cmd
may be a sequence, in which case arguments will be passed directly to the program without shell intervention (as withos.spawnv()
). Ifcmd
is a string it will be passed to the shell (as withos.system()
).
to my understanding this means that calls like:
os.popenx(['executable', 'some', 'arguments'])
are safe because no shell is invoked, while commands of the form:
os.popenx('executable some argument')
are vulnerable because a shell will be used to interpret the string as a command line.
Also note that all popen
functions are deprecated since python2.6 and should have been avoided since then. The subprocess
module provides a much better interface to launching subprocesses which is shellshock safe by default. If you don't pass the shell=True
argument your program wont launch subshells and hence wont be affected by shellshock.
To safely use subprocess
you should avoid using the shell=True
argument as much as you can (this was true even before the discovery of shellshock and is already well documented as a security hazard anyway).
In particular, if you want to simply launch an executable use subprocess.call
:
subprocess.call(['executable name', 'arg1', '--opt1', 'opt-arg', ...])
if you don't want to write the list of strings by hand you can rely on the shlex
module:
subprocess.call(shlex.split('executable-name arg1 "quoted arguments are correctly handled" etc'))
If you want to retrieve the output of the command use check_output
instead of call
.
If you want to run a pipeline of commands like cmd1 | cmd2 | cmd3
you can still avoid launching a shell:
cmd1 = subprocess.Popen(cmd1_command_line, stdout=subprocess.PIPE)
cmd2 = subprocess.Popen(cmd2_command_line, stdin=cmd1.stdout, stdout=subprocess.PIPE)
cmd3 = subprocess.Popen(cmd3_command_line, stdin=cmd2.stdout, stdout=subprocess.PIPE)
Use shell=True
only if strictly necessary, and in such a case consider explicitly passing the environment to the shell using the env
argument.
Yes, popen is affected by ShellShock. However, I do not have a comprehensive list to provide you - anything that is backed by a call to /bin/bash (such as a call to /bin/sh which links to /bin/bash - which is assumed in the below quote) is vulnerable.
A range of web apps written in PHP, Python, C++ or Java could be vulnerable if they use calls to functions such as popen() or system(), as these are backed by calls to /bin/sh -c in turn, Zalewski notes.
http://www.itnews.com.au/News/396256,further-flaws-render-shellshock-patch-ineffective.aspx
I hope this provides you a sufficient interim response to your question.