ShadowRylander
ShadowRylander

Reputation: 405

Potential security flaws with ast.parsing, compiling, then evaluating a string

Adapted from Antti Haapala's answer here, I got the code below, used with a str example, to check whether an evaluated object is a class or not:

from inspect import isclass
from ast import parse
isclass(eval(compile(parse("str", mode = "eval"), "<AST>", "eval")))
# => True

Could anyone tell me about any potential security flaws with this piece?

I tried using inspect.isclass(ast.literal_eval("str")), but got the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/ast.py", line 105, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python3.9/ast.py", line 104, in _convert
    return _convert_signed_num(node)
  File "/usr/lib/python3.9/ast.py", line 78, in _convert_signed_num
    return _convert_num(node)
  File "/usr/lib/python3.9/ast.py", line 69, in _convert_num
    _raise_malformed_node(node)
  File "/usr/lib/python3.9/ast.py", line 66, in _raise_malformed_node
    raise ValueError(f'malformed node or string: {node!r}')
ValueError: malformed node or string: <ast.Name object at 0x7fb5b8394e20>

I then tried using inspect.isclass(ast.literal_eval("'str'")), as per nojco's answer here, but while it worked, it evaluated to False.

Upvotes: 0

Views: 239

Answers (1)

a_guest
a_guest

Reputation: 36249

Yes, using eval poses a security risk. Try for example the following (side effect: this will create a directory oops):

# [!] This will create a directory 'oops'.
isclass(eval(compile(parse("__import__('os').mkdir('oops')", mode="eval"), "<AST>", "eval")))

So eval'uating arbitrary input from untrusted sources can harm your system.

Upvotes: 2

Related Questions