15 comments

[ 4.0 ms ] story [ 43.4 ms ] thread
Tl;dr do not try to create a Python sandbox it is not a good language for it.
Or create a real sandbox, with interpreter support, like the PyPy one.
(comment deleted)
Based on this exploit if not on general principle, it seems advisable to wrap a sandboxing runtime in additional protections. For example codepad.org says: "When your app is remote code execution, you have to expect security problems. Rather than rely on just the chroot and ptrace supervisor, I've taken some additional precautions: The supervisor processes run on virtual machines, which are firewalled such that they are incapable of making outgoing connections. The machines that run the virtual machines are also heavily firewalled, and restored from their source images periodically."
Given a sane language and a sane exposed API, it's not difficult to limit what the remote code can do. It's just that bolting a software-based isolation layer ("sandbox") on top of something existing can be expected to yield a few holes in the process. If I were to use anything existing, it would be something like Lua. Just strip away the standard library API and replace it with something strictly under your control.
Lua is much more sane because you have much more control of what is accessible to code than you have in Python.
Tl;dr if your code takes user input and interprets it as code, you have an inherently insecure program. Dynamic languages with lots of introspection made their work easier here, but the whole reason it was possible is because the program was intentionally insecure. The "restricted environment" was a few small hacks on top of eval, it wasn't a serious attempt to make it secure.
Did you try grabbing the code of the ``auth`` function so that you could discover what you were supposed to do?
From the article:

> You can get the code object of a function using myfunc.func_code. This is forbidden in the restricted mode of the Python interpreter, so we can’t see the code of the auth function.

I recommend Zope's Restricted Python: https://pypi.python.org/pypi/RestrictedPython for that sort of thing (this is not like Python's now-dead restricted mode).

Restricted Python will recompile your code from something like "x.y(42)" into your_getattr(x, "y")(42). It will disallow access of any names starting with _, a number of other unsafe constructs etc.

So you can set up your sandbox as restricted as you want. For example the objects I expose have each an ACL so I can give users access to some system object's specific properties while disallowing modifications of them.

You can get access to the usual builtins using a lambda function's func_globals.
Is it really news to concoct exploits against obscure, antiquated practices which nobody uses because they have been known as insecure for years?