[Python-Dev] pysandsox project
victor.stinner at haypocalc.com
Mon Feb 15 18:11:43 CET 2010
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:
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(...)
... 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
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
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.
More information about the Python-Dev