how to convert string to list or tuple

Steven Bethard steven.bethard at gmail.com
Mon May 30 12:23:45 EDT 2005


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



More information about the Python-list mailing list