Michael Spencer wrote:
Giovanni Bajo wrote:

I use something along these lines:

def safe_eval(expr, symbols={}):
return eval(expr, dict(__builtins__=None, True=True, False=False), symbols)


import math
def calc(expr):
    return safe_eval(expr, vars(math))

That offers only notional security:

 >>> calc("acos.__class__.__bases__[0]")
 <type 'object'>

Yeah, I was concerned about the same thing, but I realized that I can't actually access any of the func_globals attributes:


py> eval('(1).__class__.mro()[-1].__subclasses__()[17]'
...      '.substitute.func_globals', dict(__builtins__=None))
Traceback (most recent call last):
  File "<interactive input>", line 2, in ?
  File "<string>", line 0, in ?
RuntimeError: restricted attribute

AFAIK, you need to get to func_globals to do anything really interesting. (You can get file through object, but you can't get __import__ AFAIK. So you can read and write files which means you can create a DOS attack, but I don't know how to do the eqivalent of, say, 'rm -rf /'.)

Also interesting is that an old exec trick[1] no longer works:

py> exec """\
... global __builtins__
... del __builtins__
... print __builtins__""" in dict(__builtins__=None)
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
  File "<string>", line 3, in ?
NameError: global name '__builtins__' is not defined

(It used to make __builtins__ available.)

STeVe

[1]http://mail.python.org/pipermail/python-list/2004-August/234838.html
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to