Python Language Evaluating a string containing a Python literal with ast.literal_eval


If you have a string that contains Python literals, such as strings, floats etc, you can use ast.literal_eval to evaluate its value instead of eval. This has the added feature of allowing only certain syntax.

>>> import ast
>>> code = """(1, 2, {'foo': 'bar'})"""
>>> object = ast.literal_eval(code)
>>> object
(1, 2, {'foo': 'bar'})
>>> type(object)
<class 'tuple'>

However, this is not secure for execution of code provided by untrusted user, and it is trivial to crash an interpreter with carefully crafted input

>>> import ast
>>> ast.literal_eval('()' * 1000000)
[5]    21358 segmentation fault (core dumped)  python3

Here, the input is a string of () repeated one million times, which causes a crash in CPython parser. CPython developers do not consider bugs in parser as security issues.