Modal Title

6 Security Risks to Consider with WebAssembly

Despite its growing popularity, no technology comes without security risks. So, if you're excited to get started with Wasm, you need some guardrails.
Dec 5th, 2022 1:47pm by
Featued image for: 6 Security Risks to Consider with WebAssembly

Programs and apps are a manifestation of ideas in a digital format. If you can dream it in other languages, WebAssembly can deliver it to the browser. From games ported from Unity to PDF editing on the web and leveraging interactive data from Jupyter and Rust, WebAssembly’s use cases are countless.

WebAssembly (Wasm) is gaining traction to deliver high-performance client-side code that often cannot be created or executed by JavaScript, at least not in a performant way. The complexity is often beyond JavaScript’s ability to handle it efficiently and is better suited for other programming languages such as C# and Rust. As a portable compilation target, Wasm enables C# and Rust to be used for web applications.

WebAssembly is already being used by high-traffic, high-volume and highly established names like Figma and Google Earth, and many are looking to get started with it as well. You can find some great guides to getting started with Wasm online for building your first Wasm-based apps. However, despite its growing popularity, no technology comes without security risks. So, if you’re excited to get started with Wasm, you need to do so with some guardrails, and this article will guide you through some security considerations to keep in mind.

What Is WebAssembly?

WebAssembly is a low-level binary format for executing code on the web. It is designed to be used as a compilation target and be efficient and fast to run. Wasm makes other programming languages available in the browser through a low-level assembly-like language that compacts into binary formats.

WebAssembly’s Goals

Wasm aims to provide performance levels that extensive JavaScript web applications cannot compete with. WebAssembly was not created to replace JavaScript, but to serve as a compilation bridge between other languages and the browser by providing a safe and efficient execution environment for web applications.

Additionally, Wasm aims to enable web developers to port code easily from other platforms to the web. Rather than being platform-dependent, the code can be web accessible through a browser.

How WebAssembly Works

WebAssembly is a web standard that defines a binary format and a corresponding assembly-like text format for execution on the web. It is designed as a portable target for the compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

The web standard defines a core set of instructions, a corresponding assembler-like text format and a JavaScript API for loading and running Wasm code. It also establishes a runtime environment that includes a memory model, garbage collection and exceptions. The binary format is designed to be efficient and fast to parse, with a minimal footprint.

The uncompiled text format of Wasm was created with a human-centric approach, making it easier to read and debug. On the surface, a WebAssembly program looks like TypeScript, which also has perks JavaScript doesn’t, such as strong types and garbage collection primitives. The JavaScript API provides a way to load WebAssembly code, instantiate and run it, and access its exports. The API also provides a way to create and manipulate WebAssembly memories and tables used by the core instructions.

6 Security Risks to Consider with WebAssembly

WebAssembly is a safe and efficient format for compiling and running web applications. However, there are a couple of limitations to keep in mind when using this technology. Let’s have a look at some of them.

WebAssembly Sandbox

When it comes to web browsers, there is a constant battle between security and functionality. On the one hand, browsers must be secure to protect users from malicious actors. On the other hand, browsers need to be functional to allow users to do what they need to do online.

One of the most significant risks associated with WebAssembly is that it limits visibility into vulnerabilities. WebAssembly must run in a sandboxed environment, typically the same as the JavaScript sandbox.

This can be problematic because WebAssembly still relies on JavaScript to a certain level to perform what it needs to do. The intermingling with JavaScript means it also inherits JavaScript-based vulnerabilities as a result. A good practice would be to use the same safety precautions and measures with Wasm as you would put in place to protect your Javascript code.

Memory Management

The issues around memory management for WebAssembly are mainly because it is a virtual machine. There is no physical memory dedicated to Wasm. Instead, it relies on the memory of the host machine. Issues like memory leaks are more problematic because while JavaScript often cleans up after itself, static languages require this process to be explicit.

If a Wasm program runs out of the declared maximum or reaches the browser’s limit, the program will likely crash, causing an unsavory experience for the user. To prevent this, C++ programs have toolchains like emscripten that comes with sanitizers that can help with debugging.

Linear Memory

While both JavaScript and WebAssembly run in the browser, it doesn’t mean that the two languages can talk seamlessly to each other. Calling WebAssembly from JavaScript can result in significant memory costs because the two languages operate under different memory models.

JavaScript uses a garbage-collected heap, while WebAssembly uses linear memory space. This means that when WebAssembly is called from JavaScript, the WebAssembly linear memory space needs to be copied into the JavaScript heap, resulting in increased memory usage.

Stack Management

When a WebAssembly program is executed, the code is downloaded and stored in memory. This memory is divided into two parts: the stack and the heap. The stack is used for storing local variables and function parameters, while the heap is used for storing global variables and dynamic data structures.

The stack is managed automatically by the WebAssembly runtime. When a function is called, a new stack frame is created on the top of the stack. This stack frame contains the function’s local variables and parameters. When the function returns, the stack frame is destroyed, and the previous stack frame becomes active again.

The heap, on the other hand, is managed manually by the programmer. Heap-allocated objects must be explicitly freed when they are no longer needed, or memory leaks will occur. It is also the programmer’s responsibility to ensure that heap-allocated objects are not accessed after they have been freed.

Code Obfuscation

WebAssembly can be used to create code that is difficult to understand or reverse engineer. The code is compiled into a binary format, which is then executed by a virtual machine, so it isn’t human-readable and is also difficult to debug.

If a malicious actor can inject code into a WebAssembly module, they can take control of the machine executing it. They can steal sensitive data or even take over the entire machine. Increased cases of code injection through WebAssembly result in machine takeovers for mining cryptocurrency.

When scanning for vulnerabilities, the best method is to get right into the source code itself. This means checking for issues, bugs, potential memory leaks, security vulnerabilities and standard OWASP Top 10 issues before it gets compiled and deployed.

Lack of Integrity Checks

Integrity checks are a security measure to ensure that data has not been tampered with. There are several ways to perform integrity checks, but the most common is to use a checksum. A checksum is a value calculated based on the data in a file. The checksum will also change if the file’s data is changed. By comparing the checksum of a file to a unique value, it is possible to detect if the file has been modified.

Integrity checks are essential for security because they help detect if an attacker has tampered with a file. For example, an attacker might modify a file to bypass security checks or add malicious code. Integrity checks can also detect whether a file has been accidentally corrupted.

There is no built-in way to perform integrity checks with WebAssembly. However, it is possible to use JavaScript to perform integrity checks on WebAssembly modules, which is where security integration tools like Jit can help. The risks of not performing integrity checks on WebAssembly modules include tampered modules being executed without detection and the possibility of corrupted modules causing unexpected behavior.

Being able to run non-JavaScript-based languages in the browser is an exciting prospect. WebAssembly is excellent, but it isn’t risk-free. So if your team uses Wasm, there is a high chance that your applications may be vulnerable to attacks. Jit helps you to ensure that your WebAssembly apps and cloud orchestrations are hardened against bad actors through an easy-to-implement continuous security plan built on open source tooling. You can try it here.

Group Created with Sketch.
TNS owner Insight Partners is an investor in: Pragma, Jit.
THE NEW STACK UPDATE A newsletter digest of the week’s most important stories & analyses.