Javascript 如何在具有动态加载的、不受信任的模块的应用程序中对代码进行沙箱处理?

Javascript 如何在具有动态加载的、不受信任的模块的应用程序中对代码进行沙箱处理?,javascript,node.js,electron,Javascript,Node.js,Electron,我正在用Electron做一个游戏,我希望它支持mods。有时那些mod需要使用自定义逻辑,这就给我留下了动态加载代码的问题,我发现很难找到一种安全的方法 我所考虑的 理想情况下,我希望在执行mod脚本的同时,只传递它们所需的几个安全游戏对象作为参数,但这似乎是不可能的(无论采用何种解决方案,该代码仍然可以访问全局范围) 最重要的是,我必须防止不受信任的代码访问preload全局范围(使用节点API),因此require或在preload中执行的任何其他操作都不在窗口中 因此,必须在渲染器中执行

我正在用Electron做一个游戏,我希望它支持mods。有时那些mod需要使用自定义逻辑,这就给我留下了动态加载代码的问题,我发现很难找到一种安全的方法

我所考虑的 理想情况下,我希望在执行mod脚本的同时,只传递它们所需的几个安全游戏对象作为参数,但这似乎是不可能的(无论采用何种解决方案,该代码仍然可以访问全局范围)

最重要的是,我必须防止不受信任的代码访问
preload
全局范围(使用节点API),因此
require
或在
preload
中执行的任何其他操作都不在窗口中

因此,必须在
渲染器中执行该代码

到目前为止我的解决方案 我可以使用
fs
preload
中读取文件,也可以使用
fetch
直接在
渲染器中读取文件。我将
nodeIntegration
设置为
false
contextIsolation
设置为
true
,并且通过
contextBridge
有选择地将
preload
脚本加载的可信代码传递给
渲染器。访问节点API的代码已正确封装

不幸的是,这仍然让我不得不以某种方式执行不安全的代码,我认为除了使用
eval
函数
之外,没有其他方法。即使恶意代码无法访问节点API,它仍然可以完全访问
渲染器
全局范围,使应用程序容易受到原型污染攻击等攻击

总而言之:

  • 执行不受信任代码的更安全的地方显然是在渲染器中
  • 除了使用
    eval
    函数
  • 这使得
    渲染器
    全局范围容易受到攻击,我可以尝试减轻这些攻击,但无法使其完全安全
  • 我的第一个问题:这些假设是真的,还是有更好的方法

    风险以及如何减轻风险 因此,潜在的恶意代码可以访问
    呈现程序
    全局范围。有什么风险

    那么,任何敏感的用户数据都将安全地存储在
    预加载
    ,使用节点API访问用户的计算机也是如此。攻击者可以破坏游戏(如当前“会话”),但我可以捕获由此导致的任何错误,并在关闭恶意mod的情况下重新加载游戏。全局范围将只包含必要的构造函数,而不包含游戏类的实际实例。看起来有点安全,最糟糕的事情可能是重新加载游戏

    我的第二个问题:我是否遗漏了关于风险的任何信息?

    我的第三个问题:使用
    eval
    Function
    是否存在我没有想到的风险?
    自从我开始进入JS以来,我就一直被“eval bad”轰炸,现在我甚至考虑使用它都觉得很肮脏。确切地说,我可能会使用
    新函数


    感谢您阅读这篇长篇文章

    没有通用的解决方案,因为这在很大程度上取决于项目本身的结构

    您可以尝试使用它来解析不安全的代码,并且仅在无法访问任何全局变量时执行它

    但这很可能不会阻止所有攻击,因为您可能认为,由于程序的结构方式,
    需要
    (或包含/加载其他脚本的任何其他方式)在该不安全代码中也可能会打开允许某些攻击的侧通道

    eval
    new Function
    通常都不错,至少没有加载/以任何不同方式包含不安全代码那么糟糕。许多库对生成的代码使用代码求值,这就是这些函数的目的。但它经常被误用在不需要这样做的情况下,而这是不应该做的事情

    最安全的方法是在WebWorker中运行代码,并为mod定义API,以便mod和应用程序之间进行通信。但这需要对数据进行序列化和反序列化,当从应用程序向mod传递数据时,反过来,这可能会很昂贵(但这就是WebAssmebly所做的)。所以我会读一点关于WebAssembly如何解决通信的内容