You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Built-in properties cannot be accessed using Reflect, when Proxy is passed as vm context #7458
Associated with #6158
Empty Proxy object correctly handles this case, but unfortunately it's impossible to access 'built-in' from custom getter (using Reflect)
varassert=require('assert');varvm=require("vm");varcode="String.prototype.f = function(){}; ''.f()";// Test 1assert.strictEqual(typeofvm.runInNewContext("String",newProxy({},{})),'function');// Test 2assert.strictEqual(typeofvm.runInNewContext("String",newProxy({},{get: function(target,property,receiver){returnReflect.get(target,property);}})),'function');
Second test returns AssertionError: 'undefined' === 'function'
I'm not sure I'd expect that to work, since target is {}. I'd run
// Test 2assert.strictEqual(typeofvm.runInNewContext("String",newProxy({},{get: function(target,property,receiver){returnReflect.get(global,property);}})),'function');
Basically, contextifying a Proxy that has a handler that traps get makes it impossible to get to that contexts globals. I don't know exactly what I'd expect in this situation anyway, but this is rather unfortunate. Are there any clever workarounds we could try here?
ok, thanks, so to clarify my use-case: if you want to trap get when using a proxy object as context, explicitly add all the globals you may want to use to the target.
It seems a reasonable workaround I guess, but it still feels a bit weird to me that...
vm.runInNewContext("String",newProxy({},{}))
...works (i.e. if you're NOT trapping get), but just the act of adding the trap causes the globals to no longer be accessible. It feels like there's a hidden default implementation of get that is impossible to extend/replicate.
So I accept that this isn't a bug as-stated, but that still leaves us without any means of proxying a context global while forwarding requests to the original global.
The proposed workaround does not work, as the String being passed is now the outer context's string, not the new context String. To adapt the previous example, the following will fail:
Use vm.runInContext() to obtain a reference to this (the global object) first, then call vm.runInContext() again with the code you want to evaluate. You can then proxy to the context's global object.
Activity
fhinkel commentedon Jul 27, 2016
I'm not sure I'd expect that to work, since target is
{}. I'd runRoboPhred commentedon Nov 4, 2016
The workaround does not make use of the new context, but simply forwards the current one. This breaks the sandboxing. For example:
doughsay commentedon Jun 2, 2017
Was hoping this might be fixed in Node 8.0.0, but looks like it's still an issue:
Basically, contextifying a Proxy that has a handler that traps
getmakes it impossible to get to that contexts globals. I don't know exactly what I'd expect in this situation anyway, but this is rather unfortunate. Are there any clever workarounds we could try here?Trott commentedon Apr 29, 2018
This is still an issue in Node.js 10.0.0, right?
@nodejs/vm Does this seem like a confirmed bug? Or is it not clear that it's a bug? If it is a bug, should we add a
known_issuestest for it?devsnek commentedon Apr 29, 2018
i'm currently of the opinion that this is not a bug, for i submit to you the following:
the proxy said it had the property "String" and didn't allow property access to walk up to the next level
bnoordhuis commentedon Apr 29, 2018
I'm of the same opinion: not a bug, just misuse of proxies.
Note how
targetin #7458 (comment) is also simply the empty object:I'll close this out.
doughsay commentedon Apr 29, 2018
ok, thanks, so to clarify my use-case: if you want to trap
getwhen using a proxy object as context, explicitly add all the globals you may want to use to the target.It seems a reasonable workaround I guess, but it still feels a bit weird to me that...
...works (i.e. if you're NOT trapping
get), but just the act of adding the trap causes the globals to no longer be accessible. It feels like there's a hidden default implementation ofgetthat is impossible to extend/replicate.devsnek commentedon Apr 29, 2018
@doughsay yeah that stuff tripped me up too, you might want to take a look at proxy membranes
RoboPhred commentedon Apr 29, 2018
So I accept that this isn't a bug as-stated, but that still leaves us without any means of proxying a context global while forwarding requests to the original global.
The proposed workaround does not work, as the String being passed is now the outer context's string, not the new context String. To adapt the previous example, the following will fail:
bnoordhuis commentedon Apr 29, 2018
Use
vm.runInContext()to obtain a reference tothis(the global object) first, then callvm.runInContext()again with the code you want to evaluate. You can then proxy to the context's global object.TimothyGu commentedon Apr 29, 2018
Note other issues currently associated with using Proxy as the global: #17465 #17480 #17481