Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for running vm2 in browser #85

Open
patriksimek opened this issue Jul 30, 2017 · 19 comments
Open

Support for running vm2 in browser #85

patriksimek opened this issue Jul 30, 2017 · 19 comments

Comments

@patriksimek
Copy link
Owner

Branch: https://github.com/patriksimek/vm2/tree/feature-browsers
Library: https://github.com/patriksimek/vm2/blob/feature-browsers/dist/vm2.js

Usage

<script src="vm2.js"></script>
<script>
    const vm = new vm2.VM();
    alert(vm.run('Math.random()'));
</script>

Issues

  • Sandbox can be escaped via window.top.

TODO

  • Remove NodeVM from browser version.
  • Add BrowserVM to browser version with browser related features.
  • Automated browser tests.
@CapacitorSet
Copy link

A somewhat hacky solution could involve AST rewriting to manually wrap each property access. For instance, let x = foo.bar would be rewritten to let x = (x => (x == window.top) ? (some patch here) : x)(foo.bar).

Here is an example of AST rewriting, where function call nodes are wrapped in nodes like this.

The disadvantages to this approach are that you can't easily debug the rewritten code, and that it takes some workarounds to deal with Function, eval and the like.

@io4
Copy link

io4 commented Jul 31, 2017

I think the only way is very heavyweight that is to basically interpret JS yourself, or to replace Functions constructions with a custom implementation (such as inject variable and parse content). This method would be very hard to implement.

Variable deletion is impossible due to variables like document and top that can not be deleted nor overwritten.

@CapacitorSet
Copy link

@io4, replacing Function, eval and the like at runtime is certainly possible with AST rewriting and it's not terribly difficult either. However, it does incur a heavy performance hit, both at "compile time" since you have to rewrite literally every function call and at runtime since function calls have to go through one layer of indirection.

@stale
Copy link

stale bot commented Jan 27, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jan 27, 2019
@jafetmorales
Copy link

Please don't close, this is a relevant issue.

@patriksimek patriksimek removed the stale label Jan 30, 2019
@patriksimek
Copy link
Owner Author

I'm thinking about using web workers to get vm2 working in browsers. I'll give it a shot.

@jafetmorales
Copy link

Maybe you can put it inside a sandboxed iframe as well. That way if it escapes, it's still restricted to the frame and cannot navigate the top level browsing context.

@patriksimek
Copy link
Owner Author

The status is we can't use web workers because they don't share a memory with the host. I was testing the sandboxed iframe, but no success there either. Without the allow-same-origin option, vm2 doesn't even start. With that option enabled, I can access the top-level window. But I'm not giving up :)

@jafetmorales
Copy link

What kind of error did it give you? Did it need to access a variable? Was it missing a library? Any data that could be retrieved by exchanging messages between iframes?

@CapacitorSet
Copy link

CapacitorSet commented Aug 22, 2019

#227 is of interest, especially since Realms was mentioned specifically for browser sandboxing.

@XmiliaH
Copy link
Collaborator

XmiliaH commented Sep 19, 2019

I did try to fix the access to window with the same trick as realms-shim does.
A implementaition can be found here: https://github.com/XmiliaH/vm2/blob/feature-browsers/lib/vm.js
Disadvantage is that everthing in the vm runs in strict mode.

@john-doherty
Copy link

@patriksimek to get around the window.top issue, could you not observe the object and kill the script (throw and error) if modified/used? So, observe properties and wrap functions

Branch: https://github.com/patriksimek/vm2/tree/feature-browsers
Library: https://github.com/patriksimek/vm2/blob/feature-browsers/dist/vm2.js

Usage

<script src="vm2.js"></script>
<script>
    const vm = new vm2.VM();
    alert(vm.run('Math.random()'));
</script>

Issues

  • Sandbox can be escaped via window.top.

TODO

  • Remove NodeVM from browser version.
  • Add BrowserVM to browser version with browser related features.
  • Automated browser tests.

@XmiliaH
Copy link
Collaborator

XmiliaH commented Apr 8, 2021

I don't know of a way to observe window or window.top in a way that allows to throw before something happens.

@yalondpsi
Copy link

yalondpsi commented May 1, 2021

Hi
I need to import vm2.js as a module into typescript file.
Can someone please help? Thank you

@yalondpsi
Copy link

yalondpsi commented May 2, 2021

Hi
I need to import vm2.js as a module into typescript file.
Can someone please help? Thank you

Working as a module: added module.exports = vm2; in the end of file.

@EFF
Copy link

EFF commented Feb 1, 2022

Is support for vm2 in browser an actual thing or I need to use that long time branch ?

@XmiliaH
Copy link
Collaborator

XmiliaH commented Feb 1, 2022

As far as I know running the master branch in a browser is not safe due to access to the window global. There is a branch with browser support, however, it is outdated and insecure.

@SamuelHaidu
Copy link

This article from figma can help you https://www.figma.com/blog/how-we-built-the-figma-plugin-system/

@linonetwo
Copy link

linonetwo commented May 3, 2023

https://github.com/sablejs/sablejs can be an alternative that can run in the nodejs and browser.

The safer and faster ECMA5.1 interpreter written by JavaScript, it can be used:

  1. Sandbox (like Figma Plugin Sandbox, but better and easier to use);
  2. Protect JavaScript source code via AOT compiling to opcode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants