What are the security risks associated with WASM? - security

Using Deno you can execute WASM on a server. WASM is sandboxed for the user's safety. From my understanding, WASM code cannot do HTTP requests or modify the DOM.
Is safety guaranteed server side too? I'm looking to run arbitrary Python code from user input on servers using pyodide but was concerned that I have missed some important security flaw.

Using Deno you can run WebAssembly modules on a server because the Deno wasi module provides an implementation of WASI, the WebAssembly system interface. Using Deno is just one way of running wasm modules on a server. You could choose between many other implementations of WASI, like the wasi module in Node.js, wasmtime, lucet, wasmer, etc.
Code [running] outside of a browser needs a way to talk to the system — a system interface.
As for your security concerns, keep in mind that your WebAssembly code runs in a sandboxed environment. It's not your host system that executes directly the code in your wasm module. It's the wasm runtime — that implements the WASI interface — that runs it. And as far as I know the only way for your code to produce side effects (e.g. perform a HTTP call, access files) is to go through appropriate APIs defined by WASI.

Related

Node WASI vs spawning a child process

In the NodeJS docs it states the following:
The WASI API provides an implementation of the WebAssembly System Interface specification. WASI gives sandboxed WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions.
My question is:
What is the biggest benefit of using the WASI API over, say, spawing some other child process or similar methods of running non-nodejs code?
I would have to assume it's faster than spawning a child process, or using some C code with bindings due to the native-api.
Maybe I'm simply misunderstanding the entire idea behind WASI, which is plausable, given that part of what makes WASM so amazing is the ability to use a server-side, full blown programming language on the web (mostly), like all the crazy tools we've seen with Go/Rust.
Is this more so for the benefit of running WASM in node, natively, and again, if so, what are the benefits compared to running child processes?
I ended up getting my answer from a post here that was removed.
In really high-level terms, WASI is simply an (systems) interface for WASM.
I ended up finding this short 'article', if you will, super helpful too!
Just as WebAssembly is an assembly language for a conceptual machine, WebAssembly needs a system interface for a conceptual operating system, not any single operating system. This way, it can be run across all different OSs.
This is what WASI is — a system interface for the WebAssembly platform.

Create executable and hide application code in Node.JS

I created an application in Node.JS that sends data from a local MySQL database to a MondoDB database in a Cloud.
I want to install it on my clients without them seeing the source code and not even needing to have the Node.JS environment installed. Basically I want to turn it into an executable, as is done in Delphi, then the client would only have the executable and with that in theory it would not have access to my source code and would not even need the Node.JS environment installed, just the executable being enough.
I saw that this is possible using PKG at: https://devpleno.com/hands-on-pkg. But on the other hand I saw many threads on the subject saying that this is not effective, obfuscation techniques, but all aimed at JavaScript for the web, which is not my case, so I was worried.
In my studies on Node.JS all the examples I've seen are kept in production in the Node.JS environment with the code exposed, since they run on the server side and clients don't have access.
But in this case of distributing the app to customers, it made me think, and such doubts arose.
Does Node.JS see this? Is it best suited for this? Are there any more suitable options? Or JavaScript applications, even if they're not for the web, can't be turned into executables that actually hide the source code, and if they can't, why?

TypeScript Node Server vs Web Assembly Server

When TypeScript is properly strictly typed throughout an application it can compile to Web Assembly.
What are the performance benefits of running your server as a WebAssembly binary vs a running NodeJS server process?
What are the performance benefits of running your server as a WebAssembly binary vs a running NodeJS server process
Note that WebAssembly still needs to run in a container. The current WebAssembly containers are browsers and node
Correct Question
So the question really is What is the performance advantage of WebAssembly over JavaScript.
Answer
Performance benefits of WebAssembly over JavaScript are covered all over the internet.
Key Reason:
WebAssembly is much closer to hardware level programming.
Levels of proramming langauges:
i.e. Webassembly is low level: https://en.wikipedia.org/wiki/Low-level_programming_language and JavaScript is higher level : https://en.wikipedia.org/wiki/High-level_programming_language and therefore has overheads.
You can't do I/O from WebAssembly. It is for computation.
You send data into it via a Memory buffer, and get back a memory buffer. See the JS API sample in the docs.
You could use it for a crypto module in a webserver, but not for most of the stuff that the server does.

Can I start a socket.io/websocket server in browser?

There question about this before, the answer is no. But now, with browserify/webpack, can I just write code like I would on server and it will run in browser, or is there any restriction that would make this impossible?
No, you cannot. Starting a server in a browser requires access to low level functionality that simply to does not exist in a browser. Browserify cannot add fundamental low-level features to the browser that it does not have that would require additional native code support in order to make work.
Browserify can only package code that is either pure Javascript or is built on top of infrastructure that already exists in the browser or can be simulated with some pure javascript built on top of the features that do exist in the browser.
So, for example, you could take a crypto hash library from node.js that is pure javascript and does not rely on any capabilities that are not present in a browser and you could browserify it (e.g. repackage it) to use it in a browser. But, you could not take a node.js package that uses low-level UDP communication because the underlying access to UDP is not present in a browser.
In general, if the node.js code does I/O or manipulates other processes or uses any module that has native code, it will likely not work with browserify (there are a few work-arounds with some file I/O).
For additional info, see:
Does Browserify have any limitations?
Browserify Compatibility
So you don't say what your actual problem is that you're trying to solve, but usually you would start an actual server somewhere and have the browser connect to that server. If you wanted one particular browser session to appear to be the "master", you could certainly make your client/server behave that way. One client could be the master (appearing to essentially be the server itself) to other clients that connected to that same server. This would all be done by how you programmed your server and how it communicated with the various clients that connect to it. Actual servers can be made to be proxies for other clients where the client gets access to server-like functionality via the proxied connection to an actual server.

Is there a way to precompile node.js scripts?

Is there a way to precompile node.js scripts and distribute the binary files instead of source files?
Node already does this.
By "this" I mean creating machine-executable binary code. It does this using the JIT pattern though. More on that after I cover what others Googling for this may be searching for...
OS-native binary executable...
If by binary file instead of source, you mean a native-OS executable, yes. NW.JS and Electron both do a stellar job.
Use binaries in your node.js scripts...
If by binary file instead of source, you mean the ability to compile part of your script into binary, so it's difficult or impossible to utilize, or you want something with machine-native speed, yes.
They are called C/C++ Addons. You can distribute a binary (for your particular OS) and call it just like you would with any other var n = require("blah");
Node uses binaries "Just In Time"
Out of the box, Node pre-compiles your scripts on it's own and creates cached V8 machine code (think "executable" - it uses real machine code native to the CPU Node is running on) it then executes with each event it processes.
Here is a Google reference explaining that the V8 engine actually compiles to real machine code, and not a VM.
Google V8 JavaScript Engine Design
This compiling takes place when your application is first loaded.
It caches these bits of code as "modules" as soon as you invoke a "require('module')" instruction.
It does not wait for your entire application to be processed, but pre-compiles each module as each "require" is encountered.
Everything inside the require is compiled and introduced into memory, including it's variables and active state. Again, contrary to many popular blog articles, this is executed as individual machine-code processes. There is no VM, and nothing is interpreted. The JavaScript source is essentially compiled into an executable in memory.
This is why each module can just reference the same require and not create a bunch of overhead; it's just referencing a pre-compiled and existing object in memory, not "re-requiring" the entire module.
You can force it to recompile any module at any time. It's lesser-known that you actually have control of re-compiling these objects very easily, enabling you to "hot-reload" pieces of your application without reloading the entire thing.
A great use-case for this is creating self-modifying code, i.e. a strategy pattern that loads strategies from folders, for example, and as soon as a new folder is added, your own code can re-compile the folders into an in-line strategy pattern, create a "strategyRouter.js" file, and then invalidate the Node cache for your router which forces Node to recompile only that module, which is then utilized on future client requests.
The end result: Node can hot-reload routes or strategies as soon as you drop a new file or folder into your application. No need to restart your app, no need to separate stateless and stateful operations: Just write responses as regular Node modules and have them recompile when they change.
Note: Before people tell me self-modifying code is as bad or worse than eval, terrible for debugging and impossible to maintain, please note that Node itself does this, and so do many popular Node frameworks. I am not explaining original research, I am explaining the abilities of Google's V8 Engine (and hence Node) by design, as this question asks us to do. Please don't shoot people who R the FM, or people will stop R'ing it and keep to themselves.
"Unix was not designed to stop its users from doing stupid things, as
that would also stop them from doing clever things." – Doug Gwyn
Angular 2, Meteor, the new opensource Node-based Light table IDE and a bunch of other frameworks are headed in this direction in order to further remove the developer from the code and bring them closer to the application.
How do I recompile (hot-reload) a required Node module?
It's actually really easy... Here is a hot-reloading npm, for alternatives just Google "node require hot-reload"
https://www.npmjs.com/package/hot-reload
What if I want to build my own framework and hot-reload in an amazing new way?
That, like many things in Node, is surprisingly easy too. Node is like jQuery for servers! ;D
stackoverflow - invalidating Node's require cache

Resources