6

I'm trying to set up a Python sandbox and want to forbid access to standard and file I/O. I am running the sandbox inside of a running Python server.

I've already looked at modules like RestrictedPython and PyPy; however, I want to be able to compile the sandbox code inside of my running Python server, not through an external process.

Are there any alternative ways to prevent access to commands like print, raw_input, or open? Could the aforementioned modules be used in a way where sandbox code is compiled in a running Python program?

At worst, how would you prevent access to raw_input?

EDIT: According to this tutorial on safely evaluating Python code, would it be possible to pass in a manipulated builtins module?

Zach
  • 998
  • 1
  • 9
  • 26
  • 2
    Only PyPy sandbox is worth a damn, everything else is waste of time. – Cat Plus Plus Apr 22 '12 at 13:11
  • Can you describe what exactly is the sandbox supposed to run? Arbitrary code, user input that should be evaluated into Python objects, etc.? Do you need DoS (CPU-usage, memory exhaustion) protection? What makes separated processes bad for your use-case (keeping in mind that you usually can easily run code on your Python server that sends and fetches results to/from the separated sandboxed process)? – TryPyPy Apr 22 '12 at 21:24
  • The sandbox is supposed to run commands from user input, with mainly the restrictions I mentioned above. This was just a more simplistic option for me, since I update the environment in the call to eval/exec, and passing the environment between two processes would be more difficult. I've been investigating how to set a memory limit for the exec/eval of the commands to no avail. – Zach Apr 23 '12 at 04:54
  • Please describe "commands", preferably with example code. Memory limit requires a separate process or OS-enforced limits AFAIK. – TryPyPy Apr 23 '12 at 05:23
  • Sorry. By "commands" I mean anything you could enter into a Python shell, e.g. "x = [1,2,3]", or "map(, )". The issue of imposing memory limits is being addressed here: http://stackoverflow.com/questions/10269974/python-setting-memory-limit-for-a-particular-function-call – Zach Apr 23 '12 at 18:59

1 Answers1

5

The rough consensus on this is that the complexity and introspection abilities of CPython make for unreliable attempts of blacklisting parts of the interpreter. I believe one of the major attempts was tav's safelite. It's also not that hard to cause CPython to crash, which opens another path to be exploited from running arbitrary code. Avoiding resource exhaustion or CPU-use DoS from arbitrary code is probably impossible to do in-process (you'd need a watchdog, system limits, etc.).

Something crucial for people wanting to have sandboxed code execution in Python is to avoid rolling your own (or simply modifying sys, __builtins__): it's very easy to convince yourself it's rock solid and yet miss some obvious workaround that bypasses your protection. Keep in mind Python used to include a module that offered this kind of protection and even that had glaring issues that allowed to escape its restrictions. IIRC, it was vulnerable to fishing non-restricted objects (via introspection) into the restricted environment.

That said, pysandbox is written by a core Python developer who believes it to be safe when restricting e.g. IO (and it incorporates a lot of previous research) and can run in-process like you want (albeit with a few less features, like DoS protections from CPU and memory use).

TryPyPy
  • 6,214
  • 5
  • 35
  • 63
  • Does Pysandbox have any sort of eval command? Currently it has `execute`, which is analogous to 'exec', but it does not seem to have anything similar to `eval`. – Zach Apr 30 '12 at 20:18
  • 2
    Just to update (since I surfed here today) the pysandbox author's considered his approach not secure and not worth using. https://mail.python.org/pipermail/python-dev/2013-November/130132.html – GoingTharn Jun 10 '14 at 21:05