Python 3,ast.literal_eval(node_or_string) 中是不是有任何已知的安全漏洞?
Posted
技术标签:
【中文标题】Python 3,ast.literal_eval(node_or_string) 中是不是有任何已知的安全漏洞?【英文标题】:Python 3, Are there any known security holes in ast.literal_eval(node_or_string)?Python 3,ast.literal_eval(node_or_string) 中是否有任何已知的安全漏洞? 【发布时间】:2011-06-10 06:17:48 【问题描述】:是否有任何已知的方法可以让ast.literal_eval(node_or_string) 的评估实际上不安全?
如果是,是否有可用的补丁?
(我已经知道 PyPy[sandbox],它可能更安全,但除非答案是肯定的,否则我的需求很小,我不会走那么远。)
【问题讨论】:
【参考方案1】:documentation 声明它是安全的,并且在bug tracker 中没有与 literal_eval 的安全性相关的错误,因此您可以假设它是安全的。
另外,according to the source,literal_eval 将字符串解析为 python AST(源树),并且仅当它是文字时才返回。代码永远不会被执行,只会被解析,因此没有理由存在安全风险。
【讨论】:
+1 这里没有更多答案的原因是无需多说。 嗯,证明没有风险总是很困难,但代码从未实际执行的事实应该有助于说服风险不大。 风险和使用Python本身差不多。 不幸的是,我想使用ast.literal_eval()
来过滤输入,然后再将其传递给eval()
或exec()
,这总是存在风险。但实际上,源代码似乎表明输入是经过严格过滤的。我只是希望我没有错过任何极端情况......
如果输入是文字,literal_eval() 将返回该值。如果输入不仅仅是文字(它包含代码),那么 literal_eval() 将失败,并且执行代码会有风险。在这两种情况下,literal_eval() 都可以完成这项工作。为什么要在那之后使用 eval() 或 exec() ?【参考方案2】:
>>> code = '()' * 1000000
>>> ast.literal_eval(code)
[1] 3061 segmentation fault (core dumped) python2
或者可能更小会在 Python 2 中与 SIGSEGV
一起崩溃。在某些情况下它可能是可利用的。这个特定的错误已在 Python 3 中修复,但错误可能仍然存在于 AST 解析器中。
【讨论】:
你在literal_eval
的参数中使用了一个操作(不是字符串或节点),与literal_eval
无关。
@ProdiptaGhosh 它是一个字符串。我没有在这个答案中扩展那些 百万 括号是有充分理由的!
重点是,您首先要评估一个表达式(字符串乘以无数次,它是一个表达式,不是一个字符串)之前您正在调用literal_eval
,并且该字符串扩展与literal_eval
没有任何关系。如果事情发生了,它会得到扩展的字符串。如果出错,python 甚至在调用 literal_eval
之前就崩溃了。
好的,这让事情变得更清楚了。这似乎是一个有效的观点。与literal_eval
关系不大,但与底层parse
和compile
调用关系不大,该调用在超出最大递归限制时会出现段错误。这是一个有效的观点。我已经推翻了我的投票。对于以后的版本,这似乎也是open issue
似乎很公平,但假设您正在使用literla_eval(data)
函数不能只是在前面放一个if len(data) < 10000:
来避免这个问题?以上是关于Python 3,ast.literal_eval(node_or_string) 中是不是有任何已知的安全漏洞?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 json.loads 比 ast.literal_eval 更适合解析 JSON?
ast.literal_eval - 循环遍历列表中的字符串元素