Python:使评估安全
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3513292/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: make eval safe
提问by flybywire
I want an easy way to do a "calculator API" in Python.
我想要一种在 Python 中执行“计算器 API”的简单方法。
Right now I don't care much about the exact set of features the calculator is going to support.
现在我不太关心计算器将支持的确切功能集。
I want it to receive a string, say "1+1"and return a string with the result, in our case "2".
我希望它接收一个字符串,比如说"1+1"并返回一个带有结果的字符串,在我们的例子中"2"。
Is there a way to make evalsafe for such a thing?
有没有办法让eval这种事情变得安全?
For a start I would do
首先我会做
env = {}
env["locals"] = None
env["globals"] = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None
eval(users_str, env)
so that the caller cannot mess with my local variables (or see them).
这样调用者就不会弄乱我的局部变量(或查看它们)。
But I am sure I am overseeing a lot here.
但我确信我在这里监督了很多。
Are eval's security issues fixable or are there just too many tiny details to get it working right?
eval的安全问题是否可以修复,或者是否有太多细节无法正常工作?
采纳答案by Alex Martelli
are eval's security issues fixable or are there just too many tiny details to get it working right?
eval 的安全问题是否可以修复,或者是否有太多细节无法使其正常工作?
Definitely the latter -- a clever hacker will always manage to find a way around your precautions.
绝对是后者——聪明的黑客总会设法绕过你的预防措施。
If you're satisfied with plain expressions using elementary-type literals only, use ast.literal_eval-- that's what it's for! For anything fancier, I recommend a parsing package, such as plyif you're familiar and comfortable with the classic lexx/yacc approach, or pyparsingfor a possibly more Pythonic approach.
如果您对仅使用基本类型文字的简单表达式感到满意,请使用ast.literal_eval—— 这就是它的用途!对于任何更高级的东西,我推荐一个解析包,比如ply,如果你熟悉经典的 lexx/yacc 方法,或者pyparsing可能更像 Pythonic 方法。
回答by Katriel
The security issues are not (even close to) fixable.
安全问题无法(甚至接近于)修复。
I would use pyparsingto parse the expression into a list of tokens (this should not be too difficult, because the grammar is straightforward) and then handle the tokens individually.
我会使用pyparsing将表达式解析为一个标记列表(这应该不会太难,因为语法很简单),然后单独处理这些标记。
You could also use the astmodule to build a Python AST (since you are using valid Python syntax), but this may be open to subtle security holes.
您还可以使用该ast模块来构建 Python AST(因为您使用的是有效的 Python 语法),但这可能会导致细微的安全漏洞。
回答by Ned Batchelder
It is possible to get access to anyclass that has been defined in the process, and then you can instantiate it and invoke methods on it. It is possible to segfault the CPython interpreter, or make it quit. See this: Eval really is dangerous
可以访问在流程中定义的任何类,然后您可以实例化它并调用它的方法。可以对 CPython 解释器进行段错误,或使其退出。看到这个: Eval真的很危险
回答by Krazy Glew
Perl has a Safe eval module http://perldoc.perl.org/Safe.html
Perl 有一个 Safe eval 模块http://perldoc.perl.org/Safe.html
Googling "Python equivalent of Perl Safe" finds http://docs.python.org/2/library/rexec.html
谷歌搜索“Python 相当于 Perl Safe”发现 http://docs.python.org/2/library/rexec.html
but this Python "restricted exec" is deprecated.
但是这个 Python “restricted exec” 已被弃用。
--
——
overall, "eval" security, in any language, is a big issue. SQL injection attacks are just an example of such a security hole. Perl Safe has had security bugs over the years - most recent one I remember, it was safe, except for destructors on objects returned from the safe eval.
总的来说,“eval”安全性,在任何语言中,都是一个大问题。SQL 注入攻击只是此类安全漏洞的一个示例。Perl Safe 多年来一直存在安全漏洞——我记得最近的一个漏洞,它是安全的,除了从 safe eval 返回的对象上的析构函数。
It's the sort of thing that i might use for my own tools, but not web exposed.
这是我可能会用于我自己的工具的那种东西,但不会暴露在网络上。
However, I hope that someday fully secure evals will be available in many / any languages.
但是,我希望有一天能以多种/任何语言提供完全安全的评估。

