如果我使用eval()评估Python字符串,并且有一个类如下:
class Foo(object):
a = 3
def bar(self, x): return x + a
Run Code Online (Sandbox Code Playgroud)
如果我不信任字符串会有什么安全风险?特别是:
eval(string, {"f": Foo()}, {})不安全的?也就是说,你可以从Foo实例到达os或sys或者不安全的东西吗?eval(string, {}, {})不安全的?也就是说,我可以完全从内置像len和list到达os或sys吗?有一些不安全的字符串,如"[0]*100000000",我不在乎,因为在最坏的情况下,他们会减慢/停止程序.我主要关心的是保护程序外部的用户数据.
显然,eval(string)在大多数情况下,没有自定义词典是不安全的.
我正在制作一个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())
Run Code Online (Sandbox Code Playgroud)
问题是,我想确保此功能不会导致任何错误或错误,
如果脚本中有import语句.考虑到代码是用py2exe或py2app之类的东西编译的,这会导致任何问题吗?
我如何确保用户不能破坏程序的关键部分,如修改部分GUI,同时仍允许他们修改项目数据(数据保存在自己的模块中的全局属性中)?我认为这意味着修改传递给eval函数的全局变量dict.
如何确保此eval不会导致程序因长循环或无限循环而挂起?如何确保用户代码中引发的错误不会导致整个应用程序崩溃?
基本上,如何避免在允许用户运行自己的代码时可能出现的所有问题?
编辑:关于给出的答案
我觉得到目前为止任何答案都没有真正回答我的问题,是的,他们已经得到了部分回答,但并未完全回答.我很清楚,不可能完全停止不安全的代码.对于一个人(甚至是一个人)而言,人们过于聪明地想到绕过安全系统并阻止它们的所有方法.
事实上,如果他们这样做,我真的不在乎.我更担心一些人无意中打破了他们不知道的事情.如果有人真的想要他们可以通过脚本功能撕毁应用程序,但我不在乎.这将是他们的实例,他们创建的所有问题将在他们重新启动应用程序时消失,除非他们已经搞乱了HD上的文件.我想防止用户给某些东西愚蠢时出现的问题.
像IOError,SystaxErrors,InfiniteLoopErrors等.
现在关于范围的部分已得到解答.我现在明白如何定义可以从eval函数访问哪些函数和全局变量但是有没有办法确保如果它花费太长时间可以停止执行它们的代码?
也许是一个绿色线程系统?(绿色,因为它会让用户担心线程安全性)
此外,如果用户使用import module语句从甚至未在类的其余部分中使用的默认库加载模块.这会导致应用被Py2exe,Py2app或Freeze冻结的问题吗?如果他们称标准库的模态外?模态是否与冻结的可执行文件存在于同一目录中是否足够?
我想在没有创建新问题的情况下得到这些答案,但如果必须,我会这样做.
我有以下字符串,它是一个字典串化的Python字典:
some_string = '{123: False, 456: True, 789: False}'
Run Code Online (Sandbox Code Playgroud)
如何从上面的字符串中获取Python字典?