我有一个项目,需要允许用户在我的服务器上运行任意的、不受信任的python代码(有点像这样)。我对python相当陌生,我希望避免犯任何引入安全漏洞或其他系统漏洞的错误。是否有任何最佳实践,推荐阅读,或其他你可以给我的指示,使我的服务可用,但不是滥用?
到目前为止,我一直在考虑这样的问题:
__builtins__上下文中删除exec,以禁止使用os等潜在危险的包。用户只能使用我提供给他们的软件包。exec上下文中分配的内存总量,但我不确定是否可能。除了直接的exec之外,还有一些替代方案,但我不确定其中哪一个在这里会有帮助:
ast.NodeVisitor捕捉访问不安全对象的任何尝试。但是我应该禁止什么东西呢?PyPy或类似于沙箱的代码。注意:我知道有一个基于至少有一个 JavaScript的解释器。这在我的设想中行不通。
发布于 2013-03-22 21:40:31
Python沙箱很难。Python本质上是可内省的,在多个层次上。
这也意味着您可以从这些类型本身找到特定类型的工厂方法,并构造新的低级对象,这些对象将由解释器不受限制地直接运行。
下面是一些找到创造性的方法来打破Python沙箱的例子:
eval()真的是;eval()经常用于执行Python表达式;对于一行程序来说,它是一个原始而天真的沙箱。然后,他继续尝试将同样的原则应用于Python 3,最后通过一些有用的指针实现了成功地爆发。基本思想始终是找到一种方法来创建基本Python类型;函数和类,并通过让Python解释器执行任意(未选中的!)来突破shell!字节码。
exec语句(Python3中的exec()函数)也是如此。
所以,你想:
os,则模块命名空间中有一个本地名称os,该名称空间引用os模块。这可能会导致一个坚定的攻击者到模块,可以帮助他们打破沙箱。例如,pickle模块允许加载任意代码对象,因此,如果任何通过白名单的模块的路径导致pickle模块,则仍然存在问题。看看RestrictedPython,它试图为您提供严格的字节码控制。RestrictedPython将Python代码转换为可以控制Python2.3到2.7中允许的名称、模块和对象的东西。
如果RestrictedPython对您的目的足够安全,则取决于您实现的策略。不允许访问以下划线开头的名称,并严格地将模块白名单将是一个开始。
在我看来,唯一真正可靠的选择是使用一个单独的虚拟机,一个没有网络访问外部世界的机器,在每次运行后都会破坏它。每个新脚本都会得到一个新的VM。这样,即使代码成功地突破了Python沙箱(这并不是不可能的),所有攻击者都可以访问的时间很短,而且没有价值。
发布于 2013-03-22 21:29:09
你不可能安全地做到这一点。
如果您想安全地执行这样的操作,您必须首先实现python,它运行在一个完全受控的环境中,最好是在用户的浏览器中运行,而不是在您的系统上运行。您可以从Jython (用于java的python)开始,并将其打包为一个java。因为它将在java沙箱中运行,所以在用户的机器上,您的系统将相当安全。
发布于 2016-06-09 13:58:34
只要性能对您来说不太重要,您就可以始终在Brython中运行它,后者有效地将其放在JavaScript沙箱中
https://softwareengineering.stackexchange.com/questions/191623
复制相似问题