This approach is a logical extension of using the browser sandbox to isolate third-party libraries—like font-rendering engines and image or audio decoders that might have bugs or vulnerabilities. But WebAssembly is also built to make it easier for developers to create safe applications (and stay safe while taking dependencies on third-party code).
Because it was designed to run in the browser and avoid the security issues that plagued Flash and Active X, WebAssembly was designed for isolation without losing performance. The browser needs to be able to parse, validate and compile WASM code while a web page is loading, and that code always runs inside a sandbox.
WebAssembly is designed to try and avoid entire classes of bugs and vulnerabilities like buffer overflows and control-flow hijacking. Because languages like C and C++ use pointers to the address in memory where the value in a variable is stored, WebAssembly code needs a secure way to get access to a very specific section of memory and nothing else. WebAssembly uses a linear block of memory, and a WebAssembly module only has access to the chunk of memory assigned to it; there’s no shared memory between modules and (at least for now), and there’s no garbage collection.
WASM separates code and data. It has a static type system with type checking and a very structured control flow designed to make it easier to write code that compiles to be safe, with linear memory, global variables and stack memory accessed separately. This is also part of how WebAssembly stays portable. Although the machine code that actually runs when WASM code executes uses registers and that will be very specific to the CPU it’s running on, WebAssembly is a stack machine; rather than using registers to store data it’s operating on, WebAssembly pops data off the stack to work on and pushes the result back onto the stack.
Currently, that data is only numbers, although there’s a proposal to add reference types — like strings, sequences, records, variants — to make it easier for WASM modules to interact with modules running in other runtimes or written in different languages. Another proposal, Web IDL bindings, will let the WASM module specify the “glue” it needs to call methods on the outside objects those new types will refer to.
A WASM module doesn’t have access to APIs and system calls in the OS. If you want it to interact with anything outside the module you have to explicitly import it, so you know the only code running is what you’ve told the module about.
When WebAssembly is running inside the browser, the browser handles its access to operating system features. For running WebAssembly outside the browser, like on a server or an IoT device, some of the issues will look very familiar to cloud native developers, such as handling the concept of a file system (which you need for saving code, configuration and shared data) on services that have no file system. Giving code full access to the operating system doesn’t just open up the possibility of attacks; it also ties the code to that specific operating system.
To avoid that, WebAssembly uses the WebAssembly System Interface (WASI). It’s a modular set of system interfaces that looks like an abstracted OS, with low-level interfaces like IO and high-level interfaces like cryptography, keeping WebAssembly code portable.
This improves security because it isolates modules and gives them only fine-grained permissions for particular parts of the file system (or other resources) and system calls; different modules are isolated from each other and limited in what they could pass on to any malicious code that attempted privilege escalation. It can also improve performance, for a scenario like copying data between containers; instead of having to move data between user and kernel space, send it across the network and then reverse the process, the data can just be piped into a sidecar, using a faster and simpler calling mechanism.
But the big advantage for cloud development isn’t just security for untrusted code. It’s productivity for developers and for the cloud service providers who build SDKs for them, Terlson suggested.
Imagine a developer trying out a cloud messaging service like Azure Service Bus; they want to test their code by dropping a message into the queue, and they want that to be easy in whatever language they’re using. Just using the Azure CLI means downloading a Python interpreter because that’s the language it’s implemented in. If it delivers the long-awaited “write once, run anywhere” promise, WebAssembly could turn that on its head.