pysandbox is a Python sandbox. By default, untrusted code executed in the sandbox cannot modify the environment (write a file, use print or import a module). But you can configure the sandbox to choose exactly which features are allowed or not, eg. import sys module and read /etc/issue file.
Website: http://github.com/haypo/pysandbox/
Features
Blocked Python functions (by default):
- Deny access to the file system
- Deny importing Python modules
- Deny exiting Python
- Deny access to stdin, stdout or stderr
- Deny some builtins symbols like compile(), execfile() or KeyboardInterrupt
- Deny execution of arbitrary bytecode (creation of arbitrary code object)
A timeout of 5 seconds if used by default. You can enable all of these features by setting the sandbox configuration.
Protection of the namespace:
- Deny access to function closure, globals, defaults and code
- Deny access to frame locals
- Deny access to types subclasses
__builtins__
is read only- Deny access to dict methods able to modify a dict, eg.
dict.__setitem__
. But you can use "d[key] = value" and "del d[key]" instead
Configuration
Use SandboxConfig class to configure your sandbox. Features are the most simple way to configure it.
Features
To enable a feature, use SandboxConfig('feature1', 'feature2', ...) or config.enable('feature'). Available features:
- "codecs":
codecs
module - "code": compile()
builtin
,frame.f_locals
,frame.f_code
andgenerator.gi_code
- "debug_sandbox": allow to display a traceback of the sandbox. Enable traceback feature.
- "datetime":
datetime
module - "encodings": encodings module with ascii, latin_1, utf_8, utf_16_be, utf_32_be and rot_13 codecs (submodules). Enable codecs feature.
- "exit":
sys.exit()
,BaseException
,KeyboardInterrupt
,SystemExit
,quit()
- "future":
from __future__ import ...
- "help":
pydoc.help()
, useimport pydoc
outside the sandbox to use it. Enable regex feature. - "interpreter": give access to standard streams, enable traceback. Enable encodings, exit, site, stdin, stdout, stderr and traceback features.
- "itertools":
itertools
module - "math":
math
module - "random":
random
module. Enable math feature. - "regex": compile regex, match regex, search regex, etc. (
re
module) - "site": allow to read the license file
- "stdin":
sys.stdin
,input()
andraw_input()
- "stdout", "stderr":
sys.stdout
andsys.stderr
- "time":
time
module (exceptsleep
,strptime
andtzset
functions) - "traceback": compile()
builtin
,frame.f_code
. Next calls toallowModule()
will add the module filename to the open() whitelist, so Python can display a traceback with the source code. This feature have to be enabled before all other features. - "unicodedata":
unicodedata
module, required for u'\N{ATOM SYMBOL}' syntax
CPython restricted mode
WARNING: CPython restricted mode is unsafe because it is possible to execute arbitrary bytecode.
Use SandboxConfig(cpython_restricted=True) to enable CPython restricted mode.
In this mode, reading a file and modify a class are blocked. Some attributes
are hidden (eg. method.__self__
), other are read only (eg. func.__doc__
).
CPython restricted mode is disabled by default. The restricted mode is incompatible with SandboxConfig "traceback" feature and allowPath() method.
The restricted mode doesn't exist in Python3 anymore, it was removed with bastion and rexec modules: http://svn.python.org/view?view=rev&revision=55301
Other options
config.timeout
: timeout in seconds. Use None to disable the timeout. Default timeout value is 5 seconds.config.allowPath(path)
allows to read a file from the specified pathconfig.allowModule(name, symbol1, symbol2, ...)
allows to import the specified module, but give only access to the specified symbols
Example
With call() method:
from sandbox import Sandbox
def func(a, b):
return a + b
sandbox = Sandbox()
print sandbox.call(func, 1, 2)
With execute() method:
from sandbox import Sandbox, SandboxConfig
sandbox = Sandbox(SandboxConfig('stdout'))
sandbox.execute('print("Code executed in the sandbox")')
execute() with a local variable:
from sandbox import Sandbox, SandboxConfig
sandbox = Sandbox(SandboxConfig('stdout'))
sandbox.execute('print(data)', locals={'data': [1, 2, 3]}) # ok
sandbox.execute('data.append(4)', locals={'data': [1, 2, 3]}) # error
Objects passed to .call()
globals
/locals
and .execute()
arguments are
proxified: they are replaced by read-only views of the objects.
Limitations
pysandbox is a sandbox for the Python namespace, not a sandbox between Python and the operating system. It doesn't protect your system against Python security vulnerabilities: vulnerabilities in modules/functions available in your sandbox (depend on your sandbox configuration). By default, only few functions are exposed to the sandbox namespace which limits the attack surface.
pysandbox is unable to limit the memory of the sandbox process: you have to use your own protection.
Status
pysanbox is tested on Python 2.5 and 2.6 on Debian Sid.
See TODO file for the complete status.
See also
Python
- http://wiki.python.org/moin/SandboxedPython
- tav CPython patches: http://codereview.appspot.com/20051 http://codereview.appspot.com/21043
- secure*.py in plexnet http://github.com/tav/plexnet/tree/master/source/plexnet/util
- Security in Python Wiki: http://wiki.python.org/moin/Security
- safelite.py: http://tav.espians.com/a-challenge-to-break-python-security.html
- Zope security: http://pypi.python.org/pypi/RestrictedPython http://svn.zope.org/zope.security/trunk/src/zope/security/
- Python taint mode: http://www.cats-muvva.net/software/
- Controlling Access to Resources Within The Python Interpreter: http://www.cs.ubc.ca/~drifty/papers/python_security.pdf
- PyPy sandbox: http://codespeak.net/pypy/dist/pypy/doc/sandbox.html
- mxProxy: http://www.egenix.com/products/python/mxBase/mxProxy/
- Python 2.3: rexec and Bastion
Python-dev mailing list
- "Python jail: whitelist vs blacklist" Victor Stinner, Tue Feb 24 13:50:40 CET 2009 http://mail.python.org/pipermail/python-dev/2009-February/086444.html
- "Challenge: Please break this!" tav, Mon Feb 23 23:41:30 CET 2009 http://mail.python.org/pipermail/python-dev/2009-February/086401.html http://mail.python.org/pipermail/python-dev/2009-February/086413.html http://mail.python.org/pipermail/python-dev/2009-February/086439.html
- "Reviving restricted mode?" Guido van Rossum, Sun Feb 22 17:45:27 CET 2009 http://mail.python.org/pipermail/python-dev/2009-February/086352.html
- "object capability; func_closure; subclasses" tav, Thu Jun 28 03:04:42 CEST 2007 http://mail.python.org/pipermail/python-dev/2007-June/073724.html
- "Capabilities" Guido van Rossum, Fri, 07 Mar 2003 12:41:16 -0500 http://mail.python.org/pipermail/python-dev/2003-March/033820.html http://mail.python.org/pipermail/python-dev/2003-March/033854.html ... (read the whole archive of march and april 2003)
Other
- http://lua-users.org/wiki/SandBoxes
- "Capability-based Financial Instruments" Mark S. Miller, Chip Morningstar and Bill Frantz, 2000 http://www.erights.org/elib/capability/ode/index.html