Steven Bethard wrote:
Michael Spencer wrote:

Safe eval recipe posted to cookbook:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/364469


This recipe only evaluates constant expressions:

"Description:
Evaluate constant expressions, including list, dict and tuple using the abstract syntax tree created by compiler.parse"


It means you can't eval arbitrary Python code -- it's basically just a data parser. Handy in some situations, but not the equivalent of a limited Python virtual machine.

Indeed. But it's easy to extend this to arbitrary constructs. You just need to decide what code to emit for the other 50 or so ast node types. Many of those are boiler-plate binops.

Likewise, function calls are easily intercepted

I'm not sure I follow this... How do you intend to intercept all function calls?
Sorry, should have been more precise. In the AST, Function calls have their own node type, so it is easy to 'intercept' them and execute them conditionally

[snip]

It sounds like you're suggesting overriding the global attribute access mechanism. Is that right? So that every time Python encountered an attribute access, you would verify that the attribute being accessed is not on the 'dangerous' list?
Just in the context of the AST-walker, yes
  I don't know how to do that without
basically rewriting some of Python's C code, though certainly I'm no expert in the area...

Not messing with the CPython interpreter

Also, I'm not sure identity is sufficient:

py> import sys
py> import new
py> new.module('newsys')
py> newsys = new.module('newsys')
py> newsys.__dict__.update(sys.__dict__)
py> newsys is sys
False
py> newsys == sys
False

Right - the crux of the problem is how to identify dangerous objects. My point is that if such as test is possible, then safe exec is very easily implemented within current Python. If it is not, then it is essentially impossible.


Let's assume that it is indeed not possible to know in general whether an object is safe, either by inspecting its attributes, or by matching its identity against a black list.

It might still be possible to have a reliable test within a problem-specific domain i.e., white-listing. This, I think, is what you meant when you said:

I wish there was a way to, say, exec something with no builtins and with import 
disabled, so you would have to specify all the available bindings, e.g.:

exec user_code in dict(ClassA=ClassA, ClassB=ClassB)

I believe that if you can come up with a white-list, then the rest of the problem is easy.


Michael

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to