当我尝试提交包含eval()函数的代码时,pythontutor.com,programmr.com,coursera.org autotester等中的所有网络编译器都返回了一个名称错误。不在Web编译器上实现此功能的原因是什么?
答案 0 :(得分:4)
eval
函数肯定会被滥用,并且存在安全风险。
答案 1 :(得分:1)
可以在多个级别限制代码执行。限制代码功能的最强大工具是AST检查和AST修改。 Python代码被解析,标记化,转换为抽象语法树,最后验证和修改抽象语法树。
Eval和exec可以被滥用来偷偷搜索AST检查代码。因为在线示例不需要该功能,所以只是省略了它。
答案 2 :(得分:0)
我会抓住这个:
我不喜欢承认我错了,但在这种情况下,我认为我必须这样做。
我会指出,无论哪种方式执行使用代码仍然是正确的,因此您需要实际保护解释器。我仍然相信“如果在解释器中存在这些行为,那么试图将黑名单,甚至白名单,允许采取行动毫无意义”,因此阻止exec
和eval
只会带来微小的好处。
这是关键点:
Python Tutor的制作者执行了从外部传递给他们的代码。尽管阻止了许多事情,包括exec
,因为它们允许执行外部代码,但我发现了一个漏洞。目前我只导入了一个被阻止的模块,但是阅读源代码也可以让我做无限制的IO。
进一步编辑:我已经联系了Python Tutor的所有者,他说他已经知道了这一点,据说保护也存在于较低级别。所以它不是一种利用,但主要是因为在“较低级别”存在保护。这就是你要防范攻击的方式,而不是黑名单。
此外, 进一步编辑:我已经删除了Python Tutor,虽然该网站似乎再次启动(不起作用,只是因为我看到我是否可以通过我的这种利用来阅读/写任何东西(应业主Philip Guo的要求)。看来我至少可以打破网站:/。对不起,'这是一次意外。它确实证明运行不受信任的代码是危险的,这就是我一直在说的。
然而,问题是关于意图,而不是关于阻止exec
是否确实有所作为。
阅读http://pgbovine.net/projects/pubs/guo-sigcse-preprint_2012-11-13.pdf,即
由于后端正在从Web运行不受信任的Python代码,因此它实现了沙箱以防止执行危险的构造,例如
eval
,exec
,文件I / O和大多数模块导入(除了可自定义的模块白名单,例如math
)。
我不会承认我 / em>认为你应该这样做(虽然他确实认识到你也必须沙箱)。
首先,它几乎绝对与安全无关。默默无闻的安全永远不会奏效,尝试这是一件愚蠢的事情。您不能通过在动态语言中查找对函数的调用来将不良函数列入黑名单。一个模糊的简单例子
exec
将是
eval
所以没有保护。我会再说一遍:如果解释器中存在这些操作,那么没有任何 试图将黑名单,甚至白名单,允许的行动。这意味着任何 import os; while True: os.fork()
可以到达没有 import os
while True:
os.__dict__["fork"]()
,因此阻止eval
会为您提供否强>安全。
我认为真正的原因是这些不是典型的Python编译器解释器。代码所做的很多工作都被推到了Javascript或其他一些尴尬的平台上。
如果您深入检查代码,您将意识到在编译到字节码时,某些内容会被硬编码,例如名称绑定。当运行像“eval”这样的东西你不能只是内联运行代码时,你必须编译并动态提取范围内的东西。在目标语言中支持这种活力是一项具有挑战性的任务,作者可能只是认为这不值得做。
如果代码是在云中编译并在本地执行的,那么尤其如此:eval
因此必须到服务器进行往返才能工作!这不是建议的行动方案。
这是我的猜测,虽然我不知道这些东西是如何实际实现的。