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 个回答
15
你可以访问在程序中定义的任何类,然后你可以创建这个类的实例并调用它的方法。这样做有可能会导致CPython解释器崩溃,或者让它退出。想了解更多,可以看看这个链接:Eval真的很危险
78
eval的安全问题能解决吗,还是说有太多小细节让它难以正确工作?
肯定是后者——聪明的黑客总能找到绕过你防护的方法。
如果你只需要使用简单的表达式和基本类型的字面量,可以使用 ast.literal_eval ——这就是它的用途!如果你需要更复杂的功能,我推荐使用解析包,比如如果你熟悉传统的lex/yacc方法,可以试试 ply,或者如果你想要更符合Python风格的方式,可以考虑 pyparsing。