我将IronPython嵌入到我的游戏引擎中,您可以在其中将脚本附加到对象。我不希望脚本能够随时访问CLR,因为他们几乎可以做任何事情。
随机脚本,特别是从互联网上下载,能够打开互联网连接,访问用户硬盘或修改内部游戏状态是非常糟糕的事情。
通常人们会建议,"使用单独的AppDomain"。但是,除非我严重错误,否则跨AppDomains会很慢。非常慢。游戏引擎太慢了。所以我正在寻找其他选择。
我考虑编译IronPython的自定义版本,阻止您导入clr或任何命名空间,从而将其限制为标准库。
我宁愿选择的选项如下:
__builtins__.__import__ = None #Stops imports working
reload = None #Stops reloading working (specifically stops them reloading builtins
#giving back an unbroken __import___!
我在另一个堆栈溢出帖子中读到了这个。 假设我没有将__ builtins_ 。 _ import__设置为none,而是将其设置为允许您加载标准API的自定义函数。
问题是,使用上面概述的方法,脚本能否有任何方式能够访问clr模块,.net BCL或其他任何可能造成坏处的事情?或者我应该修改源代码?第三种选择?
答案 0 :(得分:3)
保证它的唯一方法是使用AppDomain。我不知道性能受到了什么影响;这取决于你的用例,所以你应该先测量它,以确保它实际上太慢。
如果您只需要尽力而为的系统,并且脚本不需要导入任何东西,并且您从主机提供他们需要的所有对象,那么您的方案应该是可接受的。您还可以避免运送Python标准库,这将节省一些空间。
你会想要检查其余内置的内容,以寻找可能与外界交流的内容;我想到open
,file
,input
,raw_input
和execfile
,但可能还有其他人。 exec
也可能是一个问题,因为它是一个关键字,如果那里有空缺,关闭它可能会更棘手。永远不要低估一个坚定的攻击者的能力!
答案 1 :(得分:3)
我之前在应用中嵌入了Iron Python,并分享了类似的安全问题。我为帮助降低风险所做的是为脚本运行时创建特殊对象,这些对象基本上是围绕我的核心对象的包装器,只暴露了“安全”功能。
为脚本创建对象的另一个好处是,您可以使用辅助函数对脚本进行优化,使脚本更加简洁。
Appdomain与否,没有什么能阻止某人在他们的脚本中加载外部.py模块....这是你为灵活性付出的代价。