how to convert string to list or tuple

Duncan Booth duncan.booth at invalid.invalid
Mon May 30 08:29:18 EDT 2005


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).



More information about the Python-list mailing list