Steven Bethard wrote: >> Have you tried giving it the string '__import__("os").system("rm -rf >> *")'? [Don't try that at home children!] > > But you can try it at home if you set __builtins__ to something other > than the default: > > py> eval("""__import__("os").system('echo "hello"')""", > dict(__builtins__=None)) > Traceback (most recent call last): > File "<interactive input>", line 1, in ? > File "<string>", line 0, in ? > NameError: name '__import__' is not defined > > If you're just doing work with constants, the lack of access to any > builtins is ok: > > py> eval("(1,2,3)", dict(__builtins__=None)) > (1, 2, 3) > > I know there have been security holes in this technique before, but I > looked at the archives, and all the old ones I found have been > patched. > (Or at least I wasn't able to reproduce them.) > I guess you are referring to things like this not working when you use eval with an empty __builtins__:
eval('''[ cls for cls in {}.__class__.__bases__[0].__subclasses__() if '_Printer' in `cls` ][0]._Printer__setup.func_globals['__builtins__']['__import__']''', dict(__builtins__=None)) That gets blocked because func_globals is a 'restricted attribute', so I can't get directly at __import__ that way, but what I can do is to access any new style class you have defined and call any of its methods with whatever arguments I wish. Even with the big holes patched you are going to find it pretty hard to write a safe program that uses eval on untrusted strings. The only way to go is to filter the AST (or possibly the bytecode). -- http://mail.python.org/mailman/listinfo/python-list