I'm not familiar with Genshi -- what is the purpose of the AST transformation here?
Traditionally, sandboxing environments in Python usually just exec the untrusted code in an environment with a __builtins__ dict that limits the built-in functions and overrides __import__ so as to provide an import implementation that allows import of pure-Python modules but not extensions (or only allows certain extensions that have been previously audited, or provides wrappers or subsets of selected others). --Guido On Sun, Feb 22, 2009 at 6:09 PM, Ivan Krstić <krs...@solarsail.hcs.harvard.edu> wrote: > On Feb 22, 2009, at 5:15 PM, Martin v. Löwis wrote: >> >> What is the objective of this code? Is it a complete sandbox? >> If not, is a complete sandbox based on it available somehow for >> review? > > From a cursory look at Tav's CPython patch, I'd describe it as follows: > > Requires: an existing Python code execution environment > which does not expose unsafe interpreter > functionality to the (untrusted) code it runs, > > Provides: a way for the trusted code outside of that > restricted environment to wrap functions > (which may reference trusted objects) in > closures which can be passed into the restricted > environment as completely opaque objects > whose internal state (including any referenced > trusted objects) cannot be accessed from the > untrusted code. > > When I say 'requires', I mean 'requires to be useful'; the patch can be > applied to vanilla CPython, but isn't useful on its own. > > Building blocks for a restricted execution environment as required by the > patch are commonly provided in templating libraries; Tav mentions Genshi in > particular. By default, Genshi templates don't come with security built in > -- you can do what you please in a template. However, since Genshi manually > constructs a Python AST from Python code in the template, one can restrict > the AST and modify the builtins exposed to the template environment, making > things like filesystem access, import and other sensitive system facilities > unavailable. > > Even with those unavailable, untrusted code can break out of containment by > accessing object.__subclasses__ or gaining access to gi_frame and gi_code. > This means you can't, for instance, pass into the untrusted code a closure > which operates on trusted objects. Tav's patch addresses this particular > problem. > > To give you a complete sandbox to play with, I just violently ripped out the > relevant code from Genshi, added some glue, and slapped it all together in a > single file along with Tav's pure-Python code which is functionally > equivalent to the CPython patch he submitted. The result, tested on 2.5.1 > and nothing else: > > <http://radian.org/~krstic/sandbox.py> > > As is, sandbox allows you to execute untrusted Python code which won't have > access to import, __import__, eval, exec, execfile, open, and to which you > can pass closures which reference trusted objects which the untrusted code > can't get at. > > Example: > >>>> import sandbox >>>> import sys >>>> import md5 >>>> def trusted_pwd_closure(password): > ... def get_pwd(): > ... return md5.md5(password).hexdigest() > ... return get_pwd > ... >>>> context = dict(pwd=trusted_pwd_closure('secret')) >>>> sandbox.run_string("print pwd()", context) >>>> sandbox.run_string("print pwd.func_closure[0].cell_contents", context) > [snip] > AttributeError: 'function' object has no attribute 'func_closure' > > Without Tav's patch, the untrusted code can extract our password ('secret') > from the closure with that last statement. > > To run whole files in the sandbox: >>>> sandbox.run_file('/some/path/file.py') > > Finally, disclaimer: I put this together in *15 minutes*. I'm sure I missed > something, this isn't secure, etc. It's just a proof of concept. Void where > prohibited, etc. > > Cheers, > > -- > Ivan Krstić <krs...@solarsail.hcs.harvard.edu> | http://radian.org > > -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com