0

我正在学习 Node.js (-awesome-),并且正在玩弄使用它来创建下一代 MUD(基于文本的在线游戏)的想法。在此类游戏中,有各种命令、技能、咒语等可用于在您四处奔跑并探索数百个房间/位置时杀死坏人。一般来说,这些功能是相当静态的——你通常不能创造新的法术,或者建造新的房间。但是,我想创建一个 MUD,其中定义法术和房间等的代码可以由用户编辑。

这有一些明显的安全问题;例如,恶意用户可以上传一些分叉子进程“rm -r /”的 JS。我不太关心保护游戏的内部(我会尽可能地保护,但在一切都是公开的语言中你能做的只有这么多);我总是可以跟踪 wiki 风格的代码更改,并惩罚例如使服务器崩溃的用户,或将他们的权力提高到 9000 等。但我想牢固地保护服务器的操作系统。

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

所以我想知道是否有一种方法可以“沙箱”单个节点模块。我的想法是,这样的沙箱需要简单地禁用“要求”功能,一切都会很幸福。所以,由于我在 Google/SO 上找不到任何东西,我想我会自己提出这个问题。

4

1 回答 1

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);
}

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

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

于 2013-07-10T01:06:23.230 回答