Reputation: 405
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
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