沙盒Node.js模块 - 它可以完成吗?

时间:2013-07-09 04:13:41

标签: javascript json node.js sandbox mud

我正在学习Node.js(-awesome-),我很想用它来创建下一代MUD(在线基于文本的游戏)。在这样的游戏中,有各种命令,技能,法术等可以用来杀死坏人,当你到处跑来探索数百个房间/位置时。一般来说,这些功能非常静态 - 您通常无法创建新的法术或建立新的房间。然而,我想创建一个MUD,其中用户可以编辑定义法术和房间等的代码。

这有一些明显的安全问题;例如,恶意用户可以上传一些用于处理子进程'rm -r /'的JS。我并不关心保护游戏的内部结构(我尽可能地保证,但是你能用一种公开的语言来做这么多事情);我总是可以跟踪wiki风格的代码更改,并惩罚用户,例如崩溃服务器,或增加他们的功率超过9000等。但我想坚定地保护服务器的操作系统。

我已经研究了类似问题的其他SO答案,大多数人建议运行一个沙盒版本的Node。这在我的情况下(至少不是很好)不起作用,因为我需要用户定义的JS与MUD的引擎交互,MUD的引擎本身需要与文件系统,系统命令,敏感的核心模块等交互。假设所有这些事务都可以在引擎中进行JSON编码,发送到沙盒进程,处理并通过JSON返回引擎,但如果每次调用获得玩家的生命值需要的话,这是一项昂贵的工作。传递到另一个进程。更不用说它是同步的,我宁愿避免。

所以我想知道是否有办法“沙箱”单个节点模块。我的想法是,这样的沙盒需要简单地禁用'require'功能,而且所有这些都是幸福的。所以,由于我在Google / SO上找不到任何东西,我想我自己就会提出这个问题。

1 个答案:

答案 0 :(得分:1)

好的,我今天想的更多了,我认为我有一个基本的策略:

var require = function(module) {
    throw "Uh-oh, untrusted code tried to load module '" + module + "'";
}
var module = null;
// use similar strategy for anything else susceptible

var loadUntrusted = function() {
    eval(code);
}

基本上,我们只是在本地范围内使用变量来隐藏来自eval代码的Node API,并运行代码。另一个漏洞点是Node API中传递给不受信任代码的对象。如果是缓冲区被传递给一个不受信任的对象/函数,该对象/函数可以在原型链上运行,并用自己的恶意版本替换密钥缓冲区函数。这将使所有缓冲区用于例如文件IO或管道系统命令等易受注入。

所以,如果我要在这方面取得成功,我需要将不受信任的对象划分到他们自己的世界 - 外部世界可以调用它上面的方法,但它不能调用外部世界的方法。当然,任何人都可以随意告诉我他们可以想到的有关此策略的任何进一步的安全漏洞。