Archive

Archive for October, 2008

Caution with “python -c” in your scripts

October 10th, 2008 rbu No comments

Python is a great programming language, and I use it to write almost all of my tools. But even the best tool cannot protect you from hurting yourself when you don’t know all its edges.

Python has three ways to execute your code for you: You type up a script, and let python run it (python script.py or ./script.py), you start the interactive python console (or use dev-python/ipython which is really neat) or instruct python to run a specific command via an argument (”python -c ‘print 17′”). Now, in the interactive case you often have python files lying around in your current working directory, and want to import them and then test a function. For this reason the current working directory is the first element in the module search path, in Python terms: sys.path[0] = ‘.’. Obviously, this would be a huge mistake when asking Python to run some file; you would not expect virt-manager to load its dependencies from /tmp just because you started it there. The last option, however is the corner case here: The python developers went with the way the interactive shell works, and so this happens:

rbu@peanut /tmp $ echo 'print 1' > re.py
rbu@peanut /tmp $ python -c 'import re'
1

This is not an issue in itself, as it is documented, but it certainly is something you should note when writing scripts that people are supposed to run on multi-user systems. If your shell script in /usr/bin calls “python -c” and people run the script from /tmp, they might end up executing code from Python modules a local attacker had placed there.

And that is how today, we released GLSA 200810-02 for bug 239560, a local root vulnerability “in” Portage. But in the end, it’s not even Portage’s fault. Several ebuilds (among them the ebuild for Portage 2.1 itself) used “python -c” and Portage does not change the working directory when it executes the ebuild’s bash functions. And judging from the ebuild API specification, it does not have to: The ebuilds are the ones that need to make sure Python does not include the current working directory (e.g. export PYTHONPATH). But even those rules are not written in stone, and I hope we bring forward a change of this contract.

So, if you own or distribute any shell scripts that interact with Python, please make sure you keep your Python in its cage. Oh, and check your usage of urllib2.urlopen() while at it.

Categories: planet.g.o, security Tags: