Sandpack / nodebox-runtime

Nodebox is a runtime for executing Node.js modules in the browser.
https://sandpack.codesandbox.io/docs/advanced-usage/nodebox
Other
725 stars 40 forks source link

Limitations can be avoided using a Web extension and Native Messaging #1

Closed guest271314 closed 1 year ago

guest271314 commented 1 year ago

Limitations Unfortunately, any type of runtime that does not have access to operating system-level APIs will come with certain limitations. For Nodebox, those are the following:

  • N-API modules
  • net#Sockets pointing to external IPs
  • Synchronous exec/spawn
  • async_hooks (planned for implementation)
  • Automatic process exiting - users now need to manually call process.exit before the - process is exited (planned for implementation)

Note, it is possible to run local node executable controlled from the browser using a Web extension and Native Messaging to avoid those limitations, e.g., https://github.com/guest271314/native-messaging-nodejs.

DeMoorJasper commented 1 year ago

That would be super nice to have, but unfortunately that would move away from it being a secure environment and also require an extension kind of going against the easy to setup/accessible nature of sandpack. But definitely something we can explore in the future.

guest271314 commented 1 year ago

I was just giving you a heads up. If the user already has Node.js, Deno, Bun, QuickJS, txiki.js, etc. executable on their device it doesn't really make sense to me to try to mock Node.js et al., In fact I don't think you can if you are not using V8 as the JavaScript engine. I am not sure what you mean by "secure environment"? The user is in total control of the node executable on their machine and what code will run. In any event, I'm just notifying you it is possible to run the JavaScript runtime controlled from the browser, including creating, turning on and off servers.

guest271314 commented 1 year ago

@DeMoorJasper An example of dynamically launching, controlling and executing arbitrary commands from the browser and streaming output to the browser using Native Messaging and deno which can be substituted for node https://github.com/guest271314/native-messaging-deno/tree/local-server-dynamic.

DeMoorJasper commented 1 year ago

Codesandbox's main product is sandboxes so with secure environment I mean an environment where a sandbox cannot access any of your host machine's files/network. Which is mostly impossible with your solution, deno comes close to this but still more friction.

We have microvm's for the use-case of full compatibility as that comes with the same security without the need to setup any tooling.

guest271314 commented 1 year ago

Codesandbox's main product is sandboxes so with secure environment I mean an environment where a sandbox cannot access any of your host machine's files/network.

We are dealing with the executable on the users' machine. The user decides to execute or not execute any commands locally controlled from the browser using a Web extension with Native Messaging.

Thus there is no "security" issue using a Web extension with Native Messaging.

I think users want to access their host machine.

I don't really see a point in attempting to duplicate a Node.js environment when the user has Node.js accessible or installed on the host machine. Just use the local node executable.

I wish you folks the best of luck.

arcanis commented 1 year ago

I think users want to access their host machine.

I certainly don't. Any maintainer under the sun will tell you what a massive security risk it is for us to run most repros people share with us on our bug trackers. A solution like Nodebox which allows running "in-memory" projects within the scope of the browser is perfect for this kind of use case.

guest271314 commented 1 year ago

@arcanis

I certainly don't. Any maintainer under the sun will tell you what a massive security risk it is for us to run most repros people share with us on our bug trackers.

How is it a security risk for you to run programs, shell scripts, applications on your machine that you control?

You can't really emulate running node anyway because you are not using V8 with all the bells and whistles and options https://chromium.googlesource.com/v8/v8/+/master/src/flags/flag-definitions.h. So in reality you might as well just skip installing nodebox-runtime in your machine and run the code you folks have written in the browser.

Using node executable with Native Messaging you get the actual product Node.js produced and complete control over the code you decide to run on your machine.

Good luck!

guest271314 commented 1 year ago

@arcanis

I certainly don't. Any maintainer under the sun will tell you what a massive security risk it is for us to run most repros people share with us on our bug trackers. A solution like Nodebox which allows running "in-memory" projects within the scope of the browser is perfect for this kind of use case.

Think about this very carefully.

You are proposing that users in the field install closed-source software on their host machine that the maintainers themselves cannot even talk about publicly https://github.com/codesandbox/nodebox-runtime/issues/7#issuecomment-1435971461

Unfortunately we are also not allowed to disclose those reasons, but please understand that we are deeply frustrated by the fact that we cannot open source right now. Generally it's a frustrating situation to be in, both for us and others, because we cannot disclose why. We are exploring whether we can still open source this in the future, though. And if that happens, we can post an update here.

so how are you going to fix any bugs relative to the underlying nodebox-runtime itself that the user installed on their host machine?

You can't.

Because you can't even talk about the implementation details publicly - yet this is a public repository on GitHub.

Again, good luck.

DeMoorJasper commented 1 year ago

install

Users don't really install anything, it's like visiting a web page. That's what makes it secure.

guest271314 commented 1 year ago

Users don't really install anything, it's like visiting a web page. That's what makes it secure.

https://github.com/codesandbox/nodebox-runtime#install

Install npm install @codesandbox/nodebox

DeMoorJasper commented 1 year ago

Users don't really install anything, it's like visiting a web page. That's what makes it secure.

https://github.com/codesandbox/nodebox-runtime#install

Install

npm install @codesandbox/nodebox

That package is entirely open source it's in packages/nodebox in this repo.

guest271314 commented 1 year ago

O.K. You have to install something though. Which part is closed-source?

Normally I don't install npm at all. I fetch the Node.js nightly release and get rid of everything except the node executable and just run ./node from a directory - without even installing the executable locally or system wide.

DeMoorJasper commented 1 year ago

Which part is closed-source?

The actual runtime is closed source, which is what runs in the browser on https://nodebox-runtime.codesandbox.io

That npm package is the code to interact with the runtime on that domain.

guest271314 commented 1 year ago

Don't get me wrong. I get what you are trying to do. I have done similar things using extension code. Using an iframe is fragile. Any code can remove the iframe from the document at any time. There is also ThirdPartyStoragePartitioning that can run your intent afowl, so I would suggest launching Chromium or Chrome with --disable-features=ThirdPartyStoragePartitioning to avoid iframe not working as expected. And use window.open() to avoid relying on iframes at all.

guest271314 commented 1 year ago

The actual runtime is closed source, which is what runs in the browser on https://nodebox-runtime.codesandbox.io/

Right, you are suggesting I run third-party closed-source code that you and your team can't talk about.

Why would I do that when I can just fetch the node nightly executable and run the real node locally that I am in complete control of?

Just claiming "secure" and "security" are quickly thrown out the window when the reality is third-party closed-source code that you can't talk about is being employed and relied on. You can't even really address any bugs with the runtime - can't even talk about it.

guest271314 commented 1 year ago

For your own edification re iframes and ThirdPartyStoragePartitioning see https://bugs.chromium.org/p/chromium/issues/detail?id=1411422.

guest271314 commented 1 year ago

You should be able to adapt your current code to use open() instead of an iframe using something like this https://github.com/guest271314/sw-transfer-stream/blob/main/background.js#L20-L52.

guest271314 commented 1 year ago

If the idea is just to run Node.s modules locally we can just fetch Node.js modules from unpkg or jsDelivr on the Web page. If the idea is to also have a one or more local directories to store modules we can use navigator.storage.getDirectory() to write multiple directories and files partitioned in the origin we make the call from. So if we are not really running the node executable we don't really need to install anything just to run Node.js modules locally.

lbogdan commented 1 year ago

Looks like there's some confusion about the goal and scope of the Nodebox project.

First and foremost, Nodebox is a Node.js-compatible browser runtime, that emulates / polyfills most of its own APIs to run inside a browser environment. Together with Sandpack, which is an in-browser bundler, it allows small to medium Node.js applications (including Vite / Next.js etc. applications, which have a Node.js server-side part) to run entirely inside a browser.

What is this useful for? There's two big categories of users:

It's pretty much what Sandpack was already doing for e.g. the React beta docs, but extended to libraries / applications / examples that have a hard dependency on Node.js, e.g. yarn, see #2.

Now, there are two important goals that we set when we started this, which strongly influenced our design decisions:

@guest271314 Your use case seems to be a very narrow subset of the above, where you're both the creator and the consumer, so you can trust the code you want to run, you're on a desktop OS, and you have the node binary around. In that case, sure, you can go ahead and use the browser to start and control node running directly inside your OS, but to be honest, I don't really see the value in that.

guest271314 commented 1 year ago

@lbogdan

First and foremost, Nodebox is a Node.js-compatible browser runtime, that emulates / polyfills most of its own APIs to run inside a browser environment.

That is already possible using unpkg, jsDelivr, et al.

You are not really running node at all, so while you can run source code conceived to be used in node environment, you are not really emulating node. Try reading and writing greater than 65536 from and to stdin/stdout without process.stdout._handle.setBlocking(true) and reading N bytes up until expected length. You don't have to be concerned with that native node issue because you are not really using node. Thus you are really just creating an entire different JavaScript runtime which happens to be able to execute node modules and uses Node.js specific syntax conventions.

I don't really see the value in that.

what happens?

guest271314 commented 1 year ago

@lbogdan

security - it should allow running arbitrary code inside a sandbox, with no access to your files, or ability to start processes, in the context of your OS;

The term "security" is bantied about a lot in various domains. There is no such thing as "security" re any signal communications based on the fact there is no way for you to verify your signal communications have not been intercepted and analyzed in real-time.

What you are essentially describing is ./node local_server.mjs, then navigating to https://: in the browser. Not novel. If you want for files or folders to be accessible for only that origin, as noted above you can use navigator.storage.getDirectory() to write and read files in the storage partition for that origin. Without running third-party closed source code the maintainers cannot even talk about. That is suspicious in and of itself.