Vm2: TypeError: 'get' on proxy: property 'constants' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value

Created on 7 Mar 2017  ·  15Comments  ·  Source: patriksimek/vm2

Noticed this while trying to require a dependency in a vm. Some code to reproduce:

const { NodeVM } = require("vm2");

const vm = new NodeVM({
  console: "redirect",
  sandbox: {},
  require: {
    builtin: ["fs"]
  },
  wrapper: "none"
});

vm.run("const fs = require('fs'); fs.constants");

Full stack trace:

node_modules/vm2/lib/main.js:327
            throw this._internal.Decontextify.value(e);
            ^
TypeError: 'get' on proxy: property 'constants' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '[object Object]' but got '[object Object]')
    at Object.<anonymous> (vm.js:1:91)
    at NodeVM.run (node_modules/vm2/lib/main.js:325:27)
    at Object.<anonymous> (script.js:12:4)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)
    at run (bootstrap_node.js:394:7)

Let me know if there's any other information I can give you to be helpful!

bug confirmed help wanted

Most helpful comment

I met this error when i exported a ES6 _class_ in the script used to run. it was ok after i translated it into
ES5.

All 15 comments

I'm also having quite a few issues around proxies, specifically with inheritance. I'm not sure if these issues are due to the implementation or a limitation of Proxies, but it's worth some investigation.

Also ran into this error. I'm not familiar enough with proxies to understand why the current pattern is not ok but I was able to make the error go away by adding an extra check for readonly non-configurable properties in Contextify.object.get:

    object: function(object, traps, deepTraps, flags, mock) {
        const proxy = new host.Proxy(object, host.Object.assign({
            get: (target, key, receiver) => {
                if (key === 'vmProxyTarget' && DEBUG) return object;
                if (key === 'isVMProxy') return true;
                if (mock && key in mock) return mock[key];
                if (key === 'constructor') return Object;
                if (key === '__proto__') return Object.prototype;

                                // Added code
                const config = host.Object.getOwnPropertyDescriptor(object, key);
                if (config && config.configurable === false && config.writable === false) {
                    return object[key];
                }

This seems to follow the get invariant MDN describes:

The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable data property.

But it seems to me like it would break the sandboxing

Just chiming in to note that we've run into this issue locally as well, with the above code change allowing us to bypass the problem. Also noting that this happened while using the Google Sheets node module in an almost exact copy of their quickstart guide (https://developers.google.com/sheets/api/quickstart/nodejs).

Are there any updates on this issue?

Does this fix have an effect on the known issue "It is not possible to define class that extends proxied class?" What do you mean it would break the sandboxing?

Hey, any progress on this issue?
I'm tried to use libraries like graceful-fs and got the same error.

I met this error when i exported a ES6 _class_ in the script used to run. it was ok after i translated it into
ES5.

Unfortunately, the solution posted by @mjbvz breaks the sandbox. I don't think there is a way to fix that issue - it the Proxy for read-only object can't return anything else except the original value, then we're screwed and throwing the error is the only way to keep sandbox secure.

Ideas are very welcome.

Can we get a clone in this situation?

Clone doesn't help - a clone is also a distinct value.

I meant a clone of fs.constants, so it is no longer read-only.

That would allow a sandbox to make changes to the object which could cause problems within the host's scope. You need to be very careful about what you send to the sandbox because every change to the object made by the sandbox is also effective in the host's context.

If it's read-only, do you even need a proxy to verify stuff?

Is there any update on this issue?
I am getting same issue when using googleapi node module ...

@XmiliaH Thank you! really appreciate it. It is working with latest version.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

keyosk picture keyosk  ·  64Comments

XmiliaH picture XmiliaH  ·  19Comments

KonradLinkowski picture KonradLinkowski  ·  10Comments

unxcepted picture unxcepted  ·  11Comments

CapacitorSet picture CapacitorSet  ·  13Comments