Python 3,ast.literal_eval(node_or_string) 是否有已知安全漏洞?
有没有人知道 ast.literal_eval(node_or_string) 这个函数在评估时可能不安全的情况?
如果有的话,有没有相应的补丁可以修复这些问题?
(我已经知道 PyPy[sandbox],它应该更安全,但如果答案是有问题的话,我的需求不大,所以我不会去那么远。)
2 个回答
17
>>> code = '()' * 1000000
>>> ast.literal_eval(code)
[1] 3061 segmentation fault (core dumped) python2
在Python 2中,如果使用的内存太小,可能会导致程序崩溃,并出现SIGSEGV
错误。在某些情况下,这个问题可能会被利用。这个特定的错误在Python 3中已经修复了,但在AST解析器中可能仍然存在其他问题。
94
这个功能以前被描述为“安全”,但没有解释这是什么意思,这让人误解。它的设计是为了不执行Python代码,这和更通用的
eval()
不同。它没有命名空间,也没有查找名字的功能,也不能调用外部的东西。但是,它并不是完全安全的:输入稍微复杂一点就可能导致内存耗尽或者C语言栈耗尽,从而让程序崩溃。某些输入还可能导致过度消耗CPU,造成服务拒绝。因此,不建议在不可信的数据上使用它。由于Python的AST编译器的栈深度限制,可能会导致Python解释器崩溃。根据输入的格式不正确,可能会引发
ValueError
、TypeError
、SyntaxError
、MemoryError
和RecursionError
等错误。
另外,根据源代码,literal_eval
会把字符串解析成Python的AST(抽象语法树),只有在它是字面量时才会返回。
所以,因为代码从来不会被执行,只是被解析,任意代码执行(ACE)的漏洞应该是不存在的。不过,服务拒绝(DOS)攻击是有可能的。
†这种类型的已知漏洞会被修复,但也可能存在未知的漏洞;)