Javascript 在沙盒中的NodeJ上运行客户端代码
我希望客户端能够发送将在服务器上运行的脚本。在运行脚本之前,管理员会查看脚本,但是如果没有发现漏洞,我想防止灾难发生 客户端应该只能使用API定义的函数。我的策略是使用Javascript 在沙盒中的NodeJ上运行客户端代码,javascript,node.js,virtual-machine,Javascript,Node.js,Virtual Machine,我希望客户端能够发送将在服务器上运行的脚本。在运行脚本之前,管理员会查看脚本,但是如果没有发现漏洞,我想防止灾难发生 客户端应该只能使用API定义的函数。我的策略是使用vm创建一个新的上下文,只允许访问api var vm = require('vm'); var v = 0; //incremetable via API var api = { incr:function(){ v++; } } var userCode = `(function(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(“返回此”)().process.exit(1)
如何在不影响服务器的情况下提供API(即脚本改变主上下文的能力)
类似于浏览器中的
iframe
。您可以使用.bind
更改函数的此
。例如:
var api = {
incr: (function() {
return v++;
}).bind(api)
}
请注意,这没有经过全面测试可能仍然有方法颠覆这种方法,但这将防止一些攻击。通常,首先在服务器上运行用户代码是一个坏主意,不管是VM还是no,事实上,我很惊讶Node允许这样一个陷阱。发布错误报告可能是一个好主意。您可以使用
.bind
更改函数的此
。例如:
var api = {
incr: (function() {
return v++;
}).bind(api)
}
请注意,这没有经过全面测试可能仍然有方法颠覆这种方法,但这将防止一些攻击。通常,首先在服务器上运行用户代码是一个坏主意,不管是VM还是no,事实上,我很惊讶Node允许这样一个陷阱。发布错误报告可能是个好主意。将所有函数绑定到var
api
这是一项非常复杂的任务,因为JavaScript的性质。我相信这是可以做到的,但您必须非常小心,以避免通过VM泄漏对象,而且我从未见过其他人安全地实现这一点。其他类型的攻击也是可能的,比如消耗所有内存。将所有函数绑定到varapi
的一个函数这是一项非常复杂的任务,因为JavaScript的性质。我相信这是可以做到的,但您必须非常小心,以避免通过VM泄漏对象,而且我从未见过其他人安全地实现这一点。其他类型的攻击也是可能的,比如消耗所有内存。这个想法不错,但这还不够。我添加了api.incr.constructor=null;api.incr.bind(空)关于运行客户端代码,这更像是拥有一个github项目并接受他人的贡献。这相当于在批准后运行用户代码。我希望您在项目中取得成功。祝你好运!:)incr.constructor(“returnthis;”)调用的函数是函数的构造函数(即全局函数构造函数)。“约束增量对这一点没有任何影响。”哈米奇如是说,未经测试。我只是在电话里打这个主意不错,但这还不够。我添加了api.incr.constructor=null;api.incr.bind(空)关于运行客户端代码,这更像是拥有一个github项目并接受他人的贡献。这相当于在批准后运行用户代码。我希望您在项目中取得成功。祝你好运!:)incr.constructor(“returnthis;”)调用的函数是函数的构造函数(即全局函数构造函数)。“约束增量对这一点没有任何影响。”哈米奇如是说,未经测试。我只是在电话里打这个