Use eval() safely?

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Mon Feb 22 07:07:05 CET 2010


On Mon, 22 Feb 2010 18:45:40 +1300, Gregory Ewing wrote:

> W. Martin Borgert wrote:
> 
>> def myeval(untrustedinput):
>>     return eval(untrustedinput, {"__builtins__": None},
>>                 { "abs": abs, "sin": math.sin })
>> 
>> Is it possible to define functions or import modules from the untrusted
>> input string?
> 
> This is NOT safe as it stands. It still isn't safe even if you put
> nothing in the globals dict at all.

It's *especially* not safe if you put nothing in the globals dict, 
because Python kindly rectifies that by putting the builtins into it:

>>> eval("__builtins__.keys()", {}, {})
['IndexError', 'all', 'help', 'vars', ... 'OverflowError']


>>> eval("globals()", {}, {})
{'__builtins__': {...}}
>>>
>>> eval("globals()", {'__builtins__': None}, {})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'globals' is not defined

So {'__builtins__': None} is safer than {}. Still not safe, exactly, but 
safer. Or at least you make the Black Hats work harder before they own 
your server :)




-- 
Steven



More information about the Python-list mailing list