2013-06-04 39 views
5

我正在编写一个应用程序,我希望用户能够输入角落案例的python文件。在我的脑海中,我能想到的最好办法是将其文件保存到磁盘并将位置保存到数据库,然后使用__import__()动态导入它,然后执行它。我的问题的第一部分是:这是做这件事的最好方法吗?动态读取一个python文件并安全地执行它

此外,这带来了一些相当大的安全问题。有没有办法在限制下运行他们的模块?不让它看到文件系统或任何东西?

编辑:

蟒蛇的执行将检索来自后端服务,是“正常”范围以外的数据,因此,它不会是一个完整的应用程序。它可能只是一个自定义协议的定义。

+2

http://wiki.python.org/moin/SandboxedPython ...我要把它作为答案......但真的只是读了这篇文章... –

回答

3

您可以使用compileexec内建函数的组合在内存中执行。缺点是你没有获得回溯源代码行。

虽然没有太多的安全希望。即使你制定了可笑的限制性过滤器,比如将所有内容限制在单个表达式中,并删除大多数内置函数,arbitrary code can be executed。禁止文件系统访问或访问其他操作系统资源,在Python中也很难,因为代码将在同一个进程中运行。有严格限制的儿童进程(chroot jail,ulimit等)是一种可能性,但这不仅仅是很多工作,它还排除了与宿主应用程序交互的大多数方式。

如果您的应用程序在本地运行并且具有与用户帐户相同的权限,那么最好不要担心并给予他们更多的权力,因为他们无法做任何事情/无论如何他们无法做任何事情,而且大多数限制会使任务(不管它是什么)更难/更烦人。另一方面,如果代码将在服务器上执行,忘记了在同一个进程中运行它。

+0

我是想着我可以产生jvm的沙盒实例并在其中运行jython。这样,我就可以不仅仅是python中的用户代码。那有意义吗?我也遇到了[pysandbox](https://github.com/haypo/pysandbox),但我不确定它有多合理。 –

+0

@ sir_charles804听起来可行。尽管如此,我还是很厌倦这样做,很多机会搞砸了。也就是说,我还会仔细检查这样做的任何第三方项目(例如'pysandbox')。 – delnan

+0

我同意。我想如果我这样做,它将与虚拟机。这样我相信容器。我还没有确定这是我要让用户指定角落案例的连接的方式,但是您的输入非常有帮助。谢谢! –

0

你可以考虑以下方法

class _DynamicModule(object): 
    def __init__(self, name): 
     self._name = name 

    def load(self, code): 
     execdict = {'__builtins__': __builtins__} 
     exec compile(code, '<string>', 'exec') in execdict 
     for key in execdict: 
      if not key.startswith('_'): 
       if not isinstance(execdict[key], str): 
        execdict[key].__module__ = self._name 
       setattr(self, key, execdict[key]) 
     return self 

import sys 
sys.modules['dummy_modules'] = _DynamicModule('dummy_modules').load('print ("!")') 

这仍然有相当大的安全问题。

1

你可以采取一些措施来限制权力(见我的OP评论)

但实际上我的两分钱......只要给每个用户自己的VM(也许AWS?)......他们不能这样搞砸了很多...你总是可以重新启动它...

一个更复杂的方法(但可以说更酷)将使用lex/yacc(在python中它的PLY)并定义你自己的语言(可以是python的一个有限子集)

相关问题