Vm2: 为什么大多数内置模块被代理而不是沙箱中需要的任何原因?

创建于 2017-10-17  ·  5评论  ·  资料来源: patriksimek/vm2

你好,
我试图弄清楚为什么内置模块是从主机代理的,而在 vm 中不需要。

这是我目前的设置:

const vm = new NodeVM({
        require: {
            external: true,
            context: 'sandbox',
            builtin: ['*'],
        },
    });

vm.run(...);

在VM内部,我需要一个外部模块( axios如果重要的话)并且在依赖链中它需要另一个模块( follow-redirects )来执行此操作(或多或少):

var Writable = require('stream').Writable;

function RedirectableRequest(options, responseCallback) {
// .....
}

RedirectableRequest.prototype = Object.create(Writable.prototype);

RedirectableRequest.prototype._performRequest = function () {  // <-------- this line breaks
// ..........
}

在 vm 中运行此代码会引发:TypeError:代理上的“设置”:陷阱为属性“_performRequest”返回错误。
流对象被代理到 vm。

当虚拟机内部实际需要stream时运行此代码(通过在此处删除 if 语句:https://github.com/patriksimek/vm2/blob/master/lib/sandbox.js#L133)是在职的。

在 osx 上运行节点 6.10.3。

谢谢

stale

最有用的评论

我还找到了另一种解决方案(我认为更适合范式)。

基本上,我发现上下文代码试图写入它在其上下文中创建的对象的原型,但它扩展了从另一个上下文引入的对象。

根据设置代理处理程序的文档,如果您尝试设置的对象上不存在该属性,则将调用原型设置处理程序。

所以;
目的
原型
a <-设置这个(原型上实际上不存在)
__proto__ (代理)
set: (){} <- 实际上调用这个

当调用 set 处理程序时,receiver 参数将被设置为我们试图设置的原始对象。 我的解决方案是这样的:

--- a/node_modules/vm2/lib/contextify.js
+++ b/node_modules/vm2/lib/contextify.js
@@ -17,7 +17,23 @@ const DEBUG = false;
 const OPNA = 'Operation not allowed on contextified object.';
 const ERROR_CST = Error.captureStackTrace;
 const FROZEN_TRAPS = {
-   set: (target, key) => false,
+   set: (target, key, value, receiver) => {
+       if( target !== receiver ){
+
+           Object.defineProperty(receiver, key, {
+               value: value,
+               writable: true,
+               enumerable: true,
+               configurable: true
+           })
+
+           return true;
+
+       }
+
+       return false;
+
+   },

所有5条评论

与#127相关

我继续将 if 语句更改为:

if( vm.options.require.context === 'sandbox' && modulename !== 'async_hooks' ){

我发现在节点 8.x 中我遇到了 async_hooks 的问题

我还找到了另一种解决方案(我认为更适合范式)。

基本上,我发现上下文代码试图写入它在其上下文中创建的对象的原型,但它扩展了从另一个上下文引入的对象。

根据设置代理处理程序的文档,如果您尝试设置的对象上不存在该属性,则将调用原型设置处理程序。

所以;
目的
原型
a <-设置这个(原型上实际上不存在)
__proto__ (代理)
set: (){} <- 实际上调用这个

当调用 set 处理程序时,receiver 参数将被设置为我们试图设置的原始对象。 我的解决方案是这样的:

--- a/node_modules/vm2/lib/contextify.js
+++ b/node_modules/vm2/lib/contextify.js
@@ -17,7 +17,23 @@ const DEBUG = false;
 const OPNA = 'Operation not allowed on contextified object.';
 const ERROR_CST = Error.captureStackTrace;
 const FROZEN_TRAPS = {
-   set: (target, key) => false,
+   set: (target, key, value, receiver) => {
+       if( target !== receiver ){
+
+           Object.defineProperty(receiver, key, {
+               value: value,
+               writable: true,
+               enumerable: true,
+               configurable: true
+           })
+
+           return true;
+
+       }
+
+       return false;
+
+   },

什么状态? 项目死了?

此问题已自动标记为过时,因为它最近没有活动。 如果没有进一步的活动,它将被关闭。 感谢你的贡献。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

XmiliaH picture XmiliaH  ·  19评论

seanc picture seanc  ·  3评论

keyosk picture keyosk  ·  64评论

wojpawlik picture wojpawlik  ·  4评论

somebody1234 picture somebody1234  ·  4评论