Duncan Booth wrote: > Steven Bethard wrote: > >>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 >> [snip] >> >>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
Among other things, yes, that's one of the big ones. func_globals is inaccessible. Also, IIRC the file constructor is inaccessible. > 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. Any new style class that I've defined? Or just any one I pass in as part of dict(__builtins__=None, ...)? If the former, could you elaborate? If the latter, then yes, I can see the problem. However for the case where all you pass in is dict(__builtins__=None), is there still a risk? Note that in the OP's case, all that is necessary is constant parsing, so no names need to be available. STeVe -- http://mail.python.org/mailman/listinfo/python-list