WebAssembly (WASM) is a binary instruction format for stack-based virtual machines. It is designed as a portable compilation target for programming languages, enabling deployment on the web. WASM was jointly developed by Mozilla, Google, Apple, and the W3C as a way to run complex, sandboxed applications in browser and mobile environments.
Developers can use many computer languages to write the source code and then compile them to WASM. WASM allows for diverse compatibility with languages available such as Go, Rust, C/C++, C#, Haxe, Kotlin, and Typescript. This allows developers to write smart contracts in whichever language they are familiar with, compile it with WASM and easily debug its WAT into human readable format. This promotes interoperability of several different languages. Using WASM to compile any language into executable byte code also gives platform independent code that allows their code to be run on a variety of underlying computer architectures.
Besides these benefits, one of the most important reasons why the TEA Project has adopted the WASM binary format is for its security features. Decentralized TApps run their WASM code inside of protected enclaves on the TEA mining nodes. The additional security benefits inherent with WebAssembly, including linear memory space and sandboxed execution within a VM, helps make the TEA network even more secure.
WASM Security Feature #1: Memory Safety
Linear Memory and the Function Table Reduces Common Vulnerabilities
In WASM, all function calls are numbered to correspond to an index in a function table. That means that function calls in WebAssembly cannot reference arbitrary addresses.
In WASM, the stack and the code segments are off limits. A WASM program only has access to the call interface provided to it and the linear memory region that’s been allocated to it. A WebAssembly program can’t be tricked into skipping to an arbitrary memory address. Because of the function table, only a preset number of locations are open to access, mitigating the potential attack surface. Contrast this to a typical C program that has full access to the entire process memory space.
Typical Memory Attacks That WASM Protects Against
Buffer overflow attacks involving attacker-supplied machine code are no longer possible in WASM. Buffer overflow attacks continue to be the most popular exploit available in the hacker’s toolbox. An example buffer overflow attack is to put a very long string into a form expecting an email address that ends up as an SQL command injection into a database server.
Another type of memory hack related to buffer overflows is the shellcode attack, named after the penchant for hackers to spawn remote shells via opcode on the infected target computers. In WebAssembly, bytecode is never mapped into the heap, which forms an effective safeguard agains shellcode attacks. To execute a shellcode attack, the hacker’s code would have to track the target program’s current function. And for the hacker to overwrite a function pointer in WASM using an opcode attack, the compromised function would have to be redirected to the beginning of a different function in the index table. They would need to ensure that the application code handling the hacker’s shellcode string returns to the address where the hacker’s exploit code is waiting with the exact same parameters. Not impossible, but a hack like this in a WASM binary is highly improbable.
Return-oriented programming (ROP) attacks using short sequences of instructions are impossible due to control-flow integrity confirming call targets are valid functions declared at load time. In WASM, the call stack is separate and inaccessible from the memory heap, and a binary can’t access what it can’t see.
WASM Security Feature #2: A Capabilities-based Sandbox
WASM runs within a VM, which is much safer than running on bare metal. Because WebAssembly programs run sandboxed, they can only run what they have permission to run. The WASM binary will only have access to whatever functions are exposed to it in the virtual machine which helps isolate it from the perspective of the host.
WASM also uses capability-based authority scheme. Any WASM code can only access what it claims and is allowed to access by the runtime. All system-level access logic is written into “providers” which are separate from the guest WASM logic. Any guest WASM processes will need to get approval to access these providers.
WASM executables only have access to resources that it’s been assigned privileges to. By preventing it from accessing data outside of its allowed context, the attack surface is reduced. Simply put, the binary running within WASM has less available to it to possibly tamper with.
Of course, this doesn’t make WASM impervious to poorly written code. But if the program code has bugs that causes unpredictable behavior in certain edge cases, then no harm will come to the host. The WebAssembly binary will crash and your entire system remains safe from any arbitrary code escaping the sandbox container and corrupting other parts of the system.
Arbitrary OS Level Code Exploits
The host is generally protected from arbitrary OS level code execution in WASM apps, although there remains a vulnerability in certain circumstances. In particular, arbitrary code can propagate through to the host OS if the WASM app is able to communicate with another vulnerable service. This attack vector is greatly mitigated in TEA Project nodes as all code execution happens within secure enclaves. In the TEA Project, the OS is a stripped-down version of the NixOS. There’s no internet access available to TApps as there’s no networking, and files can’t be corrupted as there isn’t any file system in our OS implementation for our decentralized computing nodes.