2013-11-04 43 views
0

要学习node.js,我正在编写一个网站,允许用户玩在线游戏黑手党。对于那些不熟悉黑手党的人来说,这是一种在论坛上最常播放的游戏,并且将不知情的多数人(“城市”)与知情少数人(“黑手党”)对抗。然而,尽管这是一个准确的简要概述,但实际上每个游戏会话都可以展示各种不同的家庭规则,这些规则可以显着改变游戏机制。我可以将用户提供的Javascript提供的图书馆白名单吗?

我希望我的网站能够处理所有这些变化。起初,我计划让我的网站实施一个可以运行所有黑手党变种的全面框架。然而,在完成了几个不同论坛上存档的完成游戏的规则集之后,我意识到合理规则和游戏机制机制的空间非常巨大,以致我基本上必须创建一个新的特定于领域的编程语言,以允许所有可能的变体。为一个简单直接的个人项目发明一种新语言是相当愚蠢的,而且目前我并不感兴趣,尤其是考虑到我手边有一个完美的语言,即JavaScript。

因此,我决定让变体作者上传一个JavaScript文件,其中包含我的网站将在适当的位置调用的变体代码。实质上,实现Mafia变体游戏逻辑的JavaScript模块(我的网站代码将要求())将作为我网站“游戏引擎”的脚本语言。认为Lua为C++游戏。不幸的是,这引起了严重的安全问题。与浏览器不同的是,节点运行的JavaScript可以访问文件系统,网络等等。因此,恶意用户上传一个删除我的硬盘驱动器内容的变体文件,或者开始比特币挖掘, 管他呢。

我的第一个想法是对每个用户上传的危险库(如'fs'和'http')的代码进行replace()转换为无效字符串,并在尝试加载文件时捕获相应的异常。然而,这种特别的黑名单技术让人感觉像是许多人更聪明/更有知识的一种方法,我可以在心跳中克服。 我真正需要的是将用户上传的代码可以访问的库加入白名单的方式。有没有一种方法可以在node.js中使用JavaScript?如果不是,你会如何建议我保证计算机的安全,我的节点服务器将尽可能运行?

我目前的策略是要求自己和少数可信用户审查,然后一致投票支持用户上传的JavaScript变体代码,然后将其引入系统,但我希望有一个更自动的方式来做到这一点。

+0

请看[我最近给出的答案](http://stackoverflow.com/a/19444133/893780),了解如何将白名单/黑名单模块设置为“需要”。但我同意@vkurchatkin,它只会解决您的问题的一个方面。 – robertklep

+0

JavaScript的一个非常棒的功能是能够在运行时定义行为,创建新的功能等。即使您要通过AST运行上传的代码,仍然可能会漏掉很多潜在的漏洞。如果您不完全信任用户,则需要找到执行自定义代码的不同方式。像.Net这样的平台能够提供比较低的信任环境。 – WiredPrairie

+0

这个答案真的很有用@roberklep。我想我只是将一个完全空的沙箱传递给'vm'模块,因为用户应该能够在一个文件中实现所有的逻辑。 – Drake

回答

2

您需要为此使用vm模块。基本上它允许在定制的上下文中运行脚本,所以你可以放任何你想要的全局变量,定义你自己的需求等。

你还应该记住,在node.js中可能会损害你的应用程序而没有任何库 - 用户可以简单地添加像while (true) {}这将停止整个过程。所以你需要在不同的进程中运行所有不受信任的代码,并准备好杀死它们,当它们开始滥用CPU或内存时。

+0

虚拟机模块看起来很有趣,谢谢。我可以看到唯一的缺点是我不能在任何runInX()函数上设置超时,但由于不可信代码将在子进程中运行,因此我只需要孩子向主服务器发送保持消息处理每个X毫秒,并按照你的建议杀掉它们,如果他们错过了。 – Drake

+0

您还应该在代码的头部添加'use strict;'以防止使用'arguments.callee.caller'破坏沙箱。 为了达到上述目的,我最近创建了[库](https://github.com/asvd/jailed),这进一步简化了应用程序和沙盒代码之间的交互。下面是一个几乎用超时执行执行控制的例子,如您所问: https://github.com/asvd/jailed/tree/master/demos/node/timeout – asvd

相关问题