Use eval() safely?

Steven D'Aprano steven at
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 :)


More information about the Python-list mailing list