我正在制作一个电子游戏,我想让它支持mods。有时,这些mods将需要使用自定义逻辑,这给我留下了动态加载代码的问题,我发现很难找到一种安全的方法。
我所想的
理想情况下,我希望执行mod脚本,同时只将它们所需的少数安全游戏对象作为参数传递,但这似乎是不可能的(不管是什么解决方案,该代码仍然可以访问全局范围)。
最重要的是,我必须防止不受信任的代码访问preload全局范围(使用Node ),因此require或在preload中执行的任何其他操作都不在窗口之内。
因此,该代码必须在renderer中执行。
到目前为止我的解决方案
我可以使用preload使用fs读取文件,也可以使用fetch直接在renderer中读取文件。我将nodeIntegration设置为false,contextIsolation设置为true,由preload脚本加载的可信代码通过contextBridge选择性地传递给renderer。访问Node的代码被正确封装。
不幸的是,这仍然让我不得不以某种方式执行不安全的代码,我认为除了使用eval或Function之外,没有别的办法了。即使恶意代码无法访问Node,它仍然可以完全访问renderer全局范围,从而使应用程序容易受到原型污染攻击。
总括而言:
eval或Function之外,别无选择renderer全局范围易受攻击的影响,我可以尝试减轻攻击,但绝不能使其完全安全。我的第一个问题:这些假设是真的吗,还是有更好的方法去做呢?
风险及如何减轻风险
因此,潜在的恶意代码可以访问renderer全局范围。风险有多大?
好的,任何敏感的用户数据都将安全地存储在preload中,使用Node访问用户的计算机也是如此。攻击者可以破坏游戏(如当前的“会话”),但我可以捕捉到由此引起的任何错误,然后用关闭的恶意mod重新加载游戏。全局范围只包含必需的构造函数,而不包含游戏类的实际实例。这似乎有点安全,可能发生的最糟糕的事情是重新负荷游戏。
我的第二个问题:我在这里有没有遗漏任何关于风险的东西?
我的第三个问题是:使用eval 或 Function 有什么风险,我没有想过吗?自从我开始使用JS以来,就一直在被“低劣”轰炸,现在我甚至考虑使用它都感到很脏。确切地说,我可能会使用new Function代替。
谢谢你阅读这篇长篇文章!
发布于 2020-04-12 12:23:46
没有通用的解决方案,因为这在很大程度上取决于项目本身的结构。
您可以尝试使用埃斯普里来解析不安全的代码,并且只在没有访问任何全局变量的情况下执行它。
但是,这很可能不会阻止所有攻击,因为您可能认为,由于程序的结构方式,不安全代码中的require (或任何其他包含/加载其他脚本的方式)也可以打开允许某些攻击的侧通道。
一般来说,eval和new Function并不坏,至少没有以任何不同的方式加载/包含不安全的代码那么糟糕。许多库对生成的代码使用代码评估,这就是这些函数的目的。但是,在没有必要这样做的情况下,它常常被滥用,这是不应该做的事情。
最安全的方法是在WebWorker中运行代码,并为mod和应用程序之间的通信定义一个API。但这需要序列化和反序列化数据,当将数据从应用程序传递给国防部时,这可能会很昂贵(但这就是使用WebAssmebly所做的)。因此,我将阅读一下如何使用WebAssembly解决通信问题。
https://stackoverflow.com/questions/61169409
复制相似问题