'_[1]' in .co_names using builtin compile() in Python 2.6

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Nov 27 17:08:50 EST 2013


On Wed, 27 Nov 2013 11:40:52 -0800, magnus.lycka at gmail.com wrote:

> What I'm really after, is to check that python expressions embedded in
> text files are: - well behaved (no syntax errors etc) - don't
> accidentally access anything it shouldn't - I serve them with the values
> they need on execution

If you are trying to get safe execution of untrusted code in Python, you 
should read this recent thread from the Python core developers:

https://mail.python.org/pipermail/python-dev/2013-November/130132.html


Probably the only way to securely sandbox untrusted Python code is to use 
operating system level security (such as a chroot jail) or an 
implementation such as PyPy which has been designed from the beginning to 
be sandboxed -- and even that may simply mean that nobody has broken out 
of PyPy's sandbox *yet*.

Looking back at your example:

compile('sin(5) * cos(6)', '<string>', 'eval').co_names

I'm not sure I understand why you inspect the co_names. What does that 
give you? You can tell that there are no syntax errors just by compiling 
it, if there are syntax errors it will raise SyntaxError.

I would pre-process the string before compiling and disallow *anything* 
containing "eval", "exec", or underscore. I'd also apply a limit to the 
total length of the string. That doesn't necessarily rule out a hostile 
user running arbitrary code, but it does make it harder.

Also, when you execute the compiled code, don't do this:

eval(code)  # No!

Instead, provide an explicit globals and locals namespace:

safe_ish_namespace = {'__builtins__': None}
eval(code, safe_ish_namespace)


Again, this increases the barrier to somebody hacking out of your sandbox 
without ruling it out altogether.

Good luck!


-- 
Steven



More information about the Python-list mailing list