Python:使eval安全

时间:2010-08-18 14:44:11

标签: python eval

我想要一种简单的方法在Python中执行“计算器API”。

现在我并不关心计算器将要支持的确切功能集。

我希望它接收一个字符串,比如"1+1"并返回一个包含结果的字符串,在我们的例子"2"中。

有没有办法让eval对这样的事情安全?

首先我会做

env = {}
env["locals"]   = None
env["globals"]  = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None

eval(users_str, env)

这样调用者就不会弄乱我的局部变量(或看到它们)。

但我相信我在这里监督很多。

eval的安全问题是否可以修复,或者是否有太多小细节才能使其正常工作?

4 个答案:

答案 0 :(得分:52)

  

是eval的安全问题可修复或   是否有太多微小的细节   让它正常工作?

绝对是后者 - 聪明的黑客总能找到解决方法。

如果您对仅使用基本类型文字的普通表达式感到满意,请使用ast.literal_eval - 这就是它的用途!对于任何更高档的人,我建议使用解析包,例如ply,如果您熟悉并熟悉经典的lexx / yacc方法,或pyparsing可能更多的Pythonic方法。

答案 1 :(得分:8)

可以访问已在进程中定义的任何类,然后可以实例化它并在其上调用方法。可以对CPython解释器进行分段,或者使其退出。请参阅:Eval really is dangerous

答案 2 :(得分:2)

安全问题不是(甚至接近)可修复的。

我会使用pyparsing将表达式解析为一个标记列表(这不应该太难,因为语法很简单),然后单独处理标记。

您也可以使用ast模块构建Python AST(因为您使用的是有效的Python语法),但这可能会对细微的安全漏洞开放。

答案 3 :(得分:1)

Perl有一个安全评估模块http://perldoc.perl.org/Safe.html

谷歌搜索“相当于Perl Safe的Python”发现 http://docs.python.org/2/library/rexec.html

但不推荐使用此Python“restricted exec”。

-

总的来说,任何语言的“eval”安全性都是一个大问题。 SQL注入攻击只是这种安全漏洞的一个例子。 Perl Safe多年来一直存在安全漏洞 - 最近的一个我记得,它是安全的,除了从安全评估返回的对象上的析构函数。

这可能是我可能用于自己的工具,但不是网络暴露。

但是,我希望有一天能够以多种语言或任何语言提供完全安全的证据。