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 关系不大,但与底层parsecompile 调用关系不大,该调用在超出最大递归限制时会出现段错误。这是一个有效的观点。我已经推翻了我的投票。对于以后的版本,这似乎也是open issue 似乎很公平,但假设您正在使用literla_eval(data) 函数不能只是在前面放一个if len(data) < 10000: 来避免这个问题?

以上是关于Python 3,ast.literal_eval(node_or_string) 中是不是有任何已知的安全漏洞?的主要内容,如果未能解决你的问题,请参考以下文章

eval与ast.literal_eval

为啥 json.loads 比 ast.literal_eval 更适合解析 JSON?

ast.literal_eval - 循环遍历列表中的字符串元素

ValueError:添加 Keras 层时带有 ast.literal_eval() 的节点或字符串格式错误

ast模块

将List的String表示形式转换为Dictionary Python