patriksimek / vm2

Advanced vm/sandbox for Node.js
MIT License
3.86k stars 293 forks source link

Accessing .buffer property on a Float32Array #523

Closed Brokray closed 1 year ago

Brokray commented 1 year ago

Hello there, I am currently using vm2 and would like to do some operations on a Float32Array in it. However, .buffer seems inaccessible, it always returns an empty object rather than a Float32Array.

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

const vm = new NodeVM();
vm.run(`
    console.log(new Float32Array([0.1,-0.2]).buffer)
`);

I guess this is something linked to the Proxies and there is no workaround it?
Would it be possible to add a custom function to the vm2 configuration that would be executed outside the vm container (allowing access to buffer)?

Thank you for your time.

XmiliaH commented 1 year ago

Maybe read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/buffer about what the buffer property should return as it seems to work as intended. The only difference is that inspection of the returned ArrayBuffer will not print details if the ArrayBuffer is from within the sandbox.

Brokray commented 1 year ago

Thank you for your quick response. I guess my real problem might be elsewhere. Here is my actual use case :

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

const vm = new NodeVM();
vm.run(`
    function float64Buffer(arr) {
      const float64Array = new Float64Array(arr);
      return Buffer.from(float64Array.buffer);
    }

    float64Buffer([0.1,0.2]);
`);

This call throws the following error :

TypeError: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object
at new NodeError in core node:internal/errors — line 393
at Function.from in core node:buffer — line 328
at ReadOnlyHandler.apply in vm2/lib/bridge.js — line 485
at float64Buffer in core vm.js — line 4
 in core vm.js — line 7
at VM2 Wrapper.apply in vm2/lib/bridge.js — line 485

And this seems to only happen in vm2, any idea why?

XmiliaH commented 1 year ago

This is happening as Buffer is actually the host Buffer and it cannot handle the proxied ArrayBuffer argument.

Brokray commented 1 year ago

Alright, thank you. It's a little bit clearer for us now.
I guess there is no workaround to this?

We were imagining passing a specific function that could be executed outside the vm2 context. We tried to pass it in the sandbox configuration field, but it is still executed in vm2, I guess it is not possible to do so?

XmiliaH commented 1 year ago

One would need to make a copy of the ArrayBuffer into the host and pass this object to Buffer.

Brokray commented 1 year ago

Thanks a lot, it does indeed work!
Do you see any drawback or security concern passing the ArrayBuffer?

XmiliaH commented 1 year ago

Last time I checked I did not find a security impact.

Brokray commented 1 year ago

Alright, thanks again for your help, have a great day!