【问题标题】:Running Client Code on Nodejs in Sandbox在沙盒中的 Nodejs 上运行客户端代码
【发布时间】:2016-06-06 03:45:10
【问题描述】:

我希望客户端能够发送将在服务器上运行的脚本。管理员会在运行之前查看脚本,但如果没有发现漏洞,我想防止灾难发生。

客户端应该只能使用 API 定义的功能。我的策略是创建使用vm 来创建一个只能访问api 的新上下文。

var vm = require('vm');

var v = 0; //incremetable via API

var api = {
    incr:function(){
        v++;
    }
}

var userCode =
`(function(api){
    api.incr();
    process.exit();     //ERROR: process is undefined
 })`;

vm.runInNewContext(userCode)(api);

console.log(v);

理论上,它看起来不错。但是,事实证明您仍然可以通过

使服务器崩溃

api.incr.constructor("return this")().process.exit(1)


如何在不损害服务器的情况下提供 API(也就是脚本更改主上下文的能力)?

浏览器中类似于iframe 的东西。

【问题讨论】:

  • 将所有函数绑定到 var api 的 this 上
  • 由于 JavaScript 的性质,这是一项非常复杂的任务。我相信这是可以做到的,但你必须非常小心,避免跨 VM 泄漏对象,而且我从未见过其他人安全地实现这一点。其他类型的攻击也是可能的,比如消耗所有内存。

标签: javascript node.js virtual-machine


【解决方案1】:

您可以使用.bind 更改函数的this。例如:

var api = {
   incr: (function() {
       return v++;
   }).bind(api)
}

请注意,这未经彻底测试。 可能还有办法颠覆这种方法,但这会阻止一些攻击。一般来说,首先在您的服务器上运行用户代码是个坏主意,无论是否使用虚拟机 我真的很惊讶 Node 允许这样的陷阱。发布有关它的错误报告可能是个好主意。

【讨论】:

  • 这个想法很好,但还不够。我添加了api.incr.constructor = null; api.incr.bind(null);,它似乎完成了这项工作。
  • 关于运行客户端代码,更像是拥有一个github项目并接受他人的贡献。这相当于批准后运行用户代码。
  • 希望您的项目取得成功。祝你好运! :)
  • incr.constructor("return this;")调用的函数是函数的构造函数(即全局函数构造函数)。绑定 incr 对此没有影响。
  • @harmic 就像说的一样,未经测试。我只是在手机里输入这个
猜你喜欢
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 2016-01-05
  • 2020-03-23
  • 1970-01-01
相关资源
最近更新 更多