我如何在纯Python中使用Python?

我正在用纯Python开发一个网页游戏,并且希望有一些简单的脚本来提供更多的dynamic游戏内容。 游戏内容可以由特权用户实时添加。

如果脚本语言可以是Python,那将会很好。 但是,由于恶意用户可能会造成严重的破坏,因此无法运行游戏所运行的环境。 是否有可能在纯Python中运行沙盒Python?

更新 :事实上,由于真正的Python支持将是过度杀伤,一个简单的脚本语言与Pythonic语法将是完美的。

如果没有任何Pythonic脚本解释器,是否还有其他使用纯Python编写的开源脚本解释器? 需求是对variables,基本条件和函数调用(而不是定义)的支持。

这实在是不平凡的。

有两种方法可以对Python进行沙箱。 一个是创build一个受限制的环境(即很less的全局variables等),并在这个环境中exec你的代码。 这就是梅萨所暗示的。 这很好,但有很多方法可以打破沙箱,造成麻烦。 在一年前的Python-dev上有一个关于这个的话题,那就是人们通过捕获exception和在内部状态中戳动来突破字节码操作。 如果你想要一个完整的语言,这是要走的路。

另一种方法是parsing代码,然后使用ast模块来踢出你不想要的结构(例如导入语句,函数调用等),然后编译其余的部分。 如果你想使用Python作为configuration语言,这是要走的路

另一种方式(这可能不适用于你,因为你正在使用GAE), PyPy沙箱 。 虽然我自己并没有使用它,但是关于intertubes的一点是,它是唯一真正的沙盒Python。

根据您对需求的描述(需求支持variables,基本条件和函数调用(而不是定义)),您可能需要评估方法2并从代码中剔除其他所有内容。 这有点棘手,但可行。

AFAIK可以在完全隔离的环境中运行代码:

 exec somePythonCode in {'__builtins__': {}}, {} 

但是在这样的环境中,你几乎可以做任何事:)(你甚至不能import一个模块;但是恶意的用户仍然可以运行一个无限的recursion或者导致内存不足)。可能你会想添加一些模块,接口给你的游戏引擎。

我不确定为什么没有人提到这一点,但Zope 2有一个叫做Python Script的东西,它正是在一个沙箱中执行的有限的Python,没有任何访问文件系统的权限,可以访问由Zope安全机构控制的其他Zope对象,import只限于一个安全的子集。

Zope总的来说是非常安全的,所以我想可能没有什么已知或明显的方法可以打破沙盒。

我不确定究竟Python脚本是如何实现的,但是function是在2000年以后。

下面是PythonScripts背后的神奇之处:详细的文档: http ://pypi.python.org/pypi/RestrictedPython – 它甚至看起来不像Zope有任何依赖关系,所以可以单独使用。

请注意,这不是用于安全地运行任意python代码(大多数随机脚本在首次导入或文件访问时将失败),而是在Python应用程序中使用Python进行有限的脚本编写。

这个答案是从我的评论,作为一个重复的封闭的问题: 来自Python的Python:限制function?

我会看看两个服务器的方法。 第一台服务器是您的代码所在的特权Web服务器。 第二个服务器是一个非常严格控制的服务器,只提供Web服务或RPC服务并运行不受信任的代码。 您为您的内容创build者提供您的自定义界面。 例如,如果您允许最终用户创build项目,则需要查看调用服务器的代码以执行以及参数设置。

这里是一个治疗药水的抽象例子。

 {function_id='healing potion', action='use', target='self', inventory_id='1234'} 

反应可能是类似的

 {hp='+5' action={destroy_inventory_item, inventory_id='1234'}} 

嗯。 这是一个思想实验,我不知道它做了什么:

您可以使用compiler包来parse脚本。 然后你可以走这棵树,在所有的标识符前加上前缀 – variables,方法名称等(也has|get|setattr调用等等) – 用一个唯一的前导码,这样他们就不可能引用你的variables。 你也可以确保compiler包本身没有被调用,也许还有其他被列入黑名单的东西,比如打开文件。 然后你发出这个python代码,然后compiler.compile它。

该文档指出, compiler软件包不在Python 3.0中,但没有提到3.0替代方法。

一般来说,这与论坛软件和如何将“安全”Javascript或HTML等列入白名单的做法是平行的。而且,他们历史上曾经跺脚过所有逃跑的logging。 但你可能有更多的运气与Python 🙂

您可能会对libref的Python语言服务部分感兴趣,以编写您自己的parsing器。

你会在这个wiki页面中find一些想法,但是看起来并不容易。

我认为你最好的select是到目前为止的答复。

您将需要parsing和清理input – 例如删除任何导入语句。

然后,您可以使用Messa的exec样本(或类似的东西)来允许代码执行仅针对您select的内置variables – 很可能是您自己定义的某种API,它使程序员能够访问您认为相关的function。