Python - 创建“脚本”系统

时间:2010-10-14 22:43:12

标签: python security scripting wxpython eval

我正在创建一个wxpython应用程序,我将使用各种冻结实用程序进行编译,以便为多个平台创建可执行文件。

该程序将成为基于图块的游戏引擎的地图编辑器

在这个应用程序中我想提供一个脚本系统,以便高级用户可以修改程序的行为,如修改项目数据,将项目导出到不同的格式等。

我希望系统能够像这样工作。

用户将他们希望运行的python脚本放入样式文本框中,然后按一个按钮执行脚本。

到目前为止,我很擅长这一切,这些都非常简单。 从文本框中获取脚本作为字符串使用内置函数compile()将其编译为cod对象,然后使用exec语句执行脚本

script = textbox.text #bla bla store the string
code = compile(script, "script", "exec") #make the code object
eval(code, globals())

问题是,我想确保此功能不会导致任何错误或错误 说脚本中是否有import语句。考虑到代码是用py2exe或py2app编译的,这会导致任何问题吗? 我如何确保用户不能破坏程序的关键部分,如修改部分GUI,同时仍然允许他们修改项目数据(数据保存在自己的模块中的全局属性中)?我认为这意味着修改传递给eval函数的全局变量dict 如何确保此eval不会导致程序因长循环或无限循环而挂起? 如何确保用户代码中引发的错误不会导致整个应用程序崩溃?

基本上,如何避免在允许用户运行自己的代码时可能出现的所有问题?

编辑:关于给出的答案

我觉得到目前为止的任何答案都没有真正回答我的问题 是的,他们已经得到部分回答,但并非完全。我很清楚,不可能完全停止不安全的代码。对于一个人(甚至是一个人)而言,人们过于聪明地想到绕过安全系统并阻止它们的所有方法。

事实上,如果他们这样做,我真的不在乎。我更担心一些人无意中打破了他们不知道的事情。如果有人真的想要他们可以通过脚本功能撕毁应用程序,但我不在乎。这将是他们的实例,他们创建的所有问题将在他们重新启动应用程序时消失,除非他们已经搞乱了HD上的文件。 我想防止用户给某些东西愚蠢时出现的问题 IOError,SystaxErrors,InfiniteLoopErrors等等。

现在关于范围的部分已经回答了。我现在明白如何定义可以从eval函数访问哪些函数和全局变量 但有没有办法确保如果花费太长时间就可以停止执行代码呢? 也许是一个绿色线程系统? (绿色,因为它会让用户担心线程的安全性)

如果用户使用import module语句从甚至未在类的其余部分中使用的默认库加载模块,那么

。这会导致应用被Py2exe,Py2app或Freeze冻结的问题吗?如果他们称标准库的模态外?模态是否与冻结的可执行文件存在于同一目录中是否足够?

我想在没有创建新问题的情况下得到这些答案,但如果必须,我会这样做。

4 个答案:

答案 0 :(得分:5)

简单回答:不要。

您可以禁止某些关键字(import)和操作,以及访问某些数据结构,但最终您会为您的高级用户提供相当大的权力。由于这是针对在用户计算机上运行的富客户端,恶意用户可能会崩溃甚至丢弃整个应用程序,如果他们真的喜欢它。但这是他们崩溃的实例。记录好并告诉人们不要碰的东西。

那就是说,我已经为执行用户输入的网络应用做了这样的事情,是的,像这样调用eval:

eval(code, {"__builtins__":None}, {safe_functions})

其中safe_functions是一个字典,包含您希望用户能够访问的{"name": func}种类型的函数。如果您的某些基本数据结构肯定,那么您的用户永远不会想要这样做,只需将其从globals中弹出,然后再将其传入。

顺便说一下,Guido刚才在他的博客上解决了这个问题。我会看看能不能找到它。

修改: found.

答案 1 :(得分:1)

简答:否

其他相关帖子:

创建安全网并不容易。细节太多,聪明的黑客都在附近:

  

关于您的设计目标:

您似乎正在尝试通过为用户提供修改大量行为和逻辑来构建可扩展系统。

最简单的选择是让他们编写一个脚本,您可以在程序运行期间评估(eval)。

然而,一个好的设计描述,范围灵活性并通过各种设计方案提供脚本机制,从配置,插件到脚本功能等。如果定义良好的脚本apis可以提供更有意义的可扩展性。它也更安全。

答案 2 :(得分:0)

我建议提供某种插件API,并允许用户以文本文件的形式提供插件。然后,您可以将它们作为模块导入到它们自己的命名空间中,捕获进程中的语法错误,并调用插件模块中定义的各种函数,再次检查错误。您可以提供一个API模块,用于定义插件模块可以访问的程序中的函数/类。这使您可以自由地在不破坏插件的情况下更改应用程序的体系结构,因为您可以调整API模块以相同的方式公开功能。

答案 3 :(得分:0)

如果您可以选择切换到Tkinter,则可以使用捆绑的tcl解释器来处理您的脚本。就此而言,如果你不启动tk事件循环,你可以用wxpython应用程序做到这一点;只需使用tcl解释器而不创建任何窗口。

由于tcl解释器是一个单独的东西,如果你小心你暴露给tcl的命令,那么崩溃python解释器几乎是不可能的。此外,tcl使创建DSL非常容易。

Python - 唯一具有内置脚本引擎的脚本语言: - )。