[Python-3000] os.popen versus subprocess.Popen
Mike Meyer
mwm at mired.org
Tue Apr 22 22:34:49 CEST 2008
On Tue, 22 Apr 2008 16:52:42 -0300 "Facundo Batista" <facundobatista at gmail.com> wrote:
> 2008/4/22, Andrew McNabb <amcnabb at mcnabbs.org>:
>
> > Here's a really simple example:
> >
> > ("bash", "-c", 'FILE="/tmp/a b c"; cat "$FILE"')
> >
> > That's pretty simple as a list of arguments. But if you do it as a
> > single string, you get:
> >
> > 'bash -c \'FILE="/tmp/a b c"; cat "$FILE"\''
> >
> > It can get much worse than this, especially if you need to use
> > backslashes.
>
> I think that force me to write a tuple or a list just in case I'd need
> to write a string that uses simple and double quotes, or backslashes,
> because it's "ugly", don't worth it.
But it's *not* because it's "ugly". It's because it's *safe*.
> What about growing the possibility of write a tuple/list *or* a
> string, and if I have a string, just use it? You could say that
> writing a plain string I incur in the risk of not enclosing the
> parameters correctly at bash level, but note that you're still doing
> that quote enclosing even in the tuple/list, and that Python normally
> treats the programmer as an adult.
No, the two cases really are different.
If you pass in a string, the shell will parse the string into a list
of strings to hand to exec, allowing a hostile user to use data
injection attacks to do all kinds of nasty things unless you're very,
very careful. Getting this right is hard.
If you pass in a list or tuple, the strings involved are passed to
exec as is. You don't have to figure out how to get the shell to parse
the string into the list you actually want; nor do you have to worry
about the shell treating something you thought was data as executable
code (at least unless you are exec'ing the shell yourself), pretty
much killing data injection attacks.
Basically, unless you're using a relatively simple, fixed string, the
right way to write this is a list or tuple of strings. While making
Popen act as if you set shell=True if you handed it a single string
might be desirable, you can't tell if said string is a constant
string, or the buggy "cat %s" % filename (whereas ("cat", filename)
isn't buggy). Further, the nature of the bug - it allows hostile users
to get your shell to execute arbitrary code - is enough to justify
not making this case any easier than it already is.
<mike
--
Mike Meyer <mwm at mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.
More information about the Python-3000
mailing list