[Python-Dev] pysandsox project

Victor Stinner victor.stinner at haypocalc.com
Mon Feb 15 18:11:43 CET 2010


Hi,

I'm working on a new sandbox project. The goal is to create an empty namespace 
and write strict rules for the interaction with the existing namespace (full 
featured Python namespace).

By default, you cannot read a file, use print, import a module or exit Python. 
But you can enable some functions by using config "features". 
Example: "regex" feature allows you to import the re module which will 
contain a subset of the real re module, just enough to match a regex.

To protect the sandbox namespace, some attributes are "hidden": function 
closure and globals, frame locals and type subclasses. __builtins__ is also 
replaced by a read-only dictionary. Objects are not directly injected in the 
sandbox namespace: a proxy is used to get a read-only view of the object.

pysandbox is based on safelite.py, project written by tav one year ago (search 
tav in python-dev archive, February 2009). I tested RestrictedPython, but the 
approach is different (rewrite bytecode) and the project is not maintained 
since 3 or 4 years (only minor updates on the documentation or the copyright 
header). pysandbox is different than RestrictedPython because it blocks 
everything by default and has simply config options to enable a set of 
features. pysandbox is different than safelite.py because it contains unit 
tests (ensure that blocked features are really blocked).

Only attributes/functions allowing to escape the sandbox are blocked. Eg. 
frames are still accessibles, only the frame locals are blocked. This 
blacklist policy is broken by design, but it's a nice way to quickly get a 
working sandbox without having to modify CPython too much.

pysandbox status is closer to a proof-of-concept than a beta version, there 
are open issues (see above). Please test it and try to break it!

--

To try pysandbox, download the last version using git clone or a tarball at:

    http://github.com/haypo/pysandbox/

You don't need to install it, use "python interpreter.py" or "python 
execfile.py yourscript.py". Use --help to get more options.

I tested pysandbox on Linux with Python 2.5, 2.6 and 2.7. I guess that it 
should work on Python 3.0 with minor changes.

--

The current syntax is:

   config = SandboxConfig(...)
   with Sandbox(config):
       ... execute untrusted code here ...

This syntax has a problem: local frame variables are not protected by a proxy, 
nor removed from the sandbox namespace. I tried to remove the frame locals, 
but Python uses STORE_FAST/LOAD_FAST bytecodes in a function, and this fast 
cache is not accessible in Python. Clear this cache may introduce unexpected 
behaviours.

pysandbox modify some structure attributes (frame.f_builtins and 
frame.f_tstate.interp.builtins) directly in memory using some ctypes tricks. 
I used that to avoid patching CPython and to get faster a working 
proof-of-concept. Set USE_CPYTHON_HACK to False (in sandbox/__init__.py) to 
disable these hacks, but they are needed to protect __builtins__ (see related 
tests).

--

By default, pysandbox doesn't use CPython restricted mode, because this mode 
is too restrictive (it's not possible to read a file or import a module). But 
pysandbox can use it with SandboxConfig(cpython_restricted=True).

--

See README file for more information and TODO file for a longer status.

Victor


More information about the Python-Dev mailing list