我想要一种简单的方法在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
的安全问题是否可以修复,或者是否有太多小细节才能使其正常工作?
答案 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多年来一直存在安全漏洞 - 最近的一个我记得,它是安全的,除了从安全评估返回的对象上的析构函数。这可能是我可能用于自己的工具,但不是网络暴露。
但是,我希望有一天能够以多种语言或任何语言提供完全安全的证据。