eval:
这是非常强大的,但如果您接受来自不受信任输入的字符串来评估,这也是非常危险的。假设正在评估的字符串是 "os.system('rm -rf /')" ?它会真正开始删除您计算机上的所有文件。
ast.literal_eval:
安全地评估表达式节点或包含 Python 文字或容器显示的字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔值、无、字节和集合。
句法:
eval(expression, globals=None, locals=None)
import ast
ast.literal_eval(node_or_string)
例子:
# python 2.x - doesn't accept operators in string format
import ast
ast.literal_eval('[1, 2, 3]') # output: [1, 2, 3]
ast.literal_eval('1+1') # output: ValueError: malformed string
# python 3.0 -3.6
import ast
ast.literal_eval("1+1") # output : 2
ast.literal_eval("{'a': 2, 'b': 3, 3:'xyz'}") # output : {'a': 2, 'b': 3, 3:'xyz'}
# type dictionary
ast.literal_eval("",{}) # output : Syntax Error required only one parameter
ast.literal_eval("__import__('os').system('rm -rf /')") # output : error
eval("__import__('os').system('rm -rf /')")
# output : start deleting all the files on your computer.
# restricting using global and local variables
eval("__import__('os').system('rm -rf /')",{'__builtins__':{}},{})
# output : Error due to blocked imports by passing '__builtins__':{} in global
# But still eval is not safe. we can access and break the code as given below
s = """
(lambda fc=(
lambda n: [
c for c in
().__class__.__bases__[0].__subclasses__()
if c.__name__ == n
][0]
):
fc("function")(
fc("code")(
0,0,0,0,"KABOOM",(),(),(),"","",0,""
),{}
)()
)()
"""
eval(s, {'__builtins__':{}})
在上面的代码中,().__class__.__bases__[0]
只有对象本身。现在我们实例化了所有的子类,这里我们的主要enter code here
目标是从中找到一个名为n的类。
我们需要从实例化的子类中进行code
对象和对象。function
这是CPython
访问对象子类和附加系统的另一种方法。
从 python 3.7 ast.literal_eval() 现在更严格了。不再允许任意数字的加减法。关联