6

我将 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__ 为无,我改为将其设置为允许您加载标准 API 的自定义函数。

问题是,使用上面概述的方法,脚本是否有任何方法能够访问 clr 模块、.net BCL 或其他任何可能做坏事的东西?还是我应该修改源?第三种选择?

4

2 回答 2

3

保证它的唯一方法是使用 AppDomain。我不知道性能受到什么影响;这取决于您的用例,因此您应该首先测量它以确保它实际上太慢了。

如果您只需要一个尽力而为的系统,并且脚本不需要导入任何东西,并且您从主机提供了它们需要的所有对象,那么您的方案应该是可以接受的。您还可以避免发布 Python 标准库,这将节省一些空间。

您需要检查其余的内置程序是否有任何可能与外界对话的内容;open, file, input, raw_input, 和execfile浮现在脑海中,但可能还有其他人。exec也可能是一个问题,因为它是一个关键字,如果那里有空缺,关闭它可能会比较棘手。永远不要低估一个坚定的攻击者的能力!

于 2012-05-29T16:10:12.550 回答
3

我之前在应用程序中嵌入了 Iron Python,并分享了类似的安全问题。我为帮助降低风险所做的工作是为脚本运行时创建特殊对象,这些对象本质上是围绕我的核心对象的包装器,仅公开“安全”功能。

仅为脚本创建对象的另一个好处是,您可以使用帮助函数优化它们以进行脚本编写,从而使您的脚本更加简洁和整洁。

Appdomain 与否,没有什么可以阻止某人在他们的脚本中加载外部 .py 模块......这是您为灵活性付出的代价。

于 2012-11-06T14:31:24.237 回答