Sanitizing untrusted code for eval()

Jim Washington jwashin at vt.edu
Mon Aug 22 09:55:45 EDT 2005


I'm still working on yet another parser for JSON (http://json.org).  It's
called minjson, and it's tolerant on input, strict on output, and pretty
fast. The only problem is, it uses eval(). It's important to sanitize the
incoming untrusted code before sending it to eval().  Because eval() is
evil http://blogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx
apparently in every language.

A search for potential trouble with eval() in python turned up the
following.

1.  Multiplication and exponentiation, particularly in concert with
strings, can do a DoS on the server, e.g., 'x'*9**99**999**9999

2.  lambda can cause mischief, and therefore is right out.

3.  Introspection can expose other methods to the untrusted code. e.g.,
{}.__class__.__bases__[0].__subclasses__... can climb around in the
object hierarchy and execute arbitrary methods.

4.  List comprehensions might be troublesome, though it's not clear to me
how a DoS or exploit is possible with these.  But presuming potential
trouble, 'for' is also right out.  It's not in the JSON spec anyway.

So, the above seems to indicate disallowing "*", "__", "lambda", and "for"
anywhere outside a string in the untrusted code.  Raise an error before
sending to eval().

I'm using eval() with proper __builtins__ and locals, e.g., 

result =eval(aString,
        {"__builtins__":{'True':True,'False':False,'None':None}},
        {'null':None,'true':True,'false':False})

I am familiar with this thread:
http://groups-beta.google.com/group/comp.lang.python/browse_thread/thread/cbcc21b95af0d9cc

Does anyone know of any other "gotchas" with eval() I have not found?  Or
is eval() simply too evil?

-Jim Washington



More information about the Python-list mailing list