Python 'eval'函数在列表反序列化中的安全性
Python 'eval'函数在列表反序列化中的安全性
在这种情况下会发生任何安全漏洞吗:
eval(repr(unsanitized_user_input), {"__builtins__": None}, {"True":True, "False":False})
其中unsanitized_user_input
是一个字符串对象。该字符串是由用户生成的,可能很糟糕。假设我们的Web框架没有失效,它是真正的Python内置字符串实例。
如果这很危险,我们能否对输入进行任何处理以使其安全?
我们绝不想执行字符串中包含的任何内容。
另请参见:
我相信这不是问题的基本内容,我们有成千上万个这样的:
repr([unsanitized_user_input_1, unsanitized_user_input_2, unsanitized_user_input_3, unsanitized_user_input_4, ...])
在某些情况下嵌套:
repr([[unsanitized_user_input_1, unsanitized_user_input_2], [unsanitized_user_input_3, unsanitized_user_input_4], ...])
这些本身会使用repr()
转换为字符串,存储在持久性存储中,并最终通过eval读取到内存中。
Eval从持久存储反序列化字符串比pickle和simplejson快得多。解释器是Python 2.5,因此json和ast不可用。不允许使用C模块,也不允许使用cPickle。
admin 更改状态以发布 2023年5月21日
确实很危险,最安全的替代方案是ast.literal_eval
(请参阅标准库中的ast模块)。当然,您可以构建和修改一个ast
,以提供例如在评估结果AST(当变量等减少到文字)之前对其进行计算等的功能。
eval
可能的漏洞始于它所能获取的任何对象(例如这里的True
),并通过.__class_到其类型对象等一直到object
,然后获取其子类……基本上它可以获得任何对象类型并造成破坏。我可以更具体,但我不想在公共论坛上这样做(该漏洞众所周知,但考虑到仍有多少人忽略它,将其透露给想要成为脚本小子的人可能会使事情变得更糟……只需避免在未经过滤的用户输入上使用eval
,就可以幸福地生活!)。