【问题标题】: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],它可能更安全,但除非答案是肯定的,否则我的需求很小,我不会走那么远。)

【问题讨论】:

    标签: python python-3.x security abstract-syntax-tree


    【解决方案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: 来避免这个问题?
    猜你喜欢
    • 2010-09-30
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多