WebAssembly lets you run compiled code in the browser and on servers at near-native speed, and its sandbox is genuinely stronger than running native binaries. But the security model has edges that developers regularly misread, and the recent crop of browser-based attacks has made those edges harder to ignore.
The core appeal is straightforward: WASM gives you memory safety at the sandbox boundary, type-checked function calls, and structured control flow that blocks the kind of arbitrary jumps attackers chain in native exploits. The module validates before execution, runs in the same-origin context as the page, and keeps its memory separate from the JavaScript heap. These are real guarantees. The problem is what happens inside the sandbox, and what happens when the sandbox meets the rest of your stack.
Linear memory is predictable, and that matters
WASM uses a flat, contiguous byte array for all data. Your heap, your stack, your data structures, all sit at fixed offsets from the base address. There's no ASLR inside WASM linear memory. In native code, address space layout randomization makes it hard for an attacker to predict where to write. In WASM, the layout is deterministic.
If you compiled a C library to WASM and that library has a buffer overflow, the overflow still exists. It's contained within the WASM sandbox, so it can't corrupt the browser's V8 heap or touch JavaScript objects directly. But inside linear memory, the attacker knows exactly where the stack begins, where data structures sit, and where the shadow stack return addresses live. A buffer overflow in WASM linear memory is more predictable than the same bug in native code with ASLR. The sandbox stops the bug from reaching the host. It doesn't stop the bug from corrupting the WASM application's own state.
This catches teams who compile legacy C code to WASM as a "sandboxing" measure. The isolation from the host is real. The memory corruption within the module is also real, and the deterministic layout makes it easier to exploit than it would be natively.
Spectre made WASM a first-class attack surface
WASM was one of the primary vectors through which Spectre attacks were demonstrated to be practical in browsers. The reason is performance: WASM's execution characteristics make the timing measurements required for speculative execution side channels more accurate than with JavaScript. The attack leaks data from memory the code should not be able to access, using the CPU's speculative execution engine as the mechanism.
Browser vendors responded aggressively. Timer resolution dropped across all web APIs. SharedArrayBuffer was temporarily disabled. Site isolation put each cross-origin page in its own process. These mitigations make Spectre harder to execute reliably in practice. They do not make it impossible.
The residual risk is specific: high-performance WASM applications that implement their own timing loops, for cryptographic operations or game engines, create side channels with higher resolution than the reduced-precision browser APIs. If your WASM module does constant-time comparisons for security-sensitive operations, it needs the same review you'd give a native cryptographic implementation. The sandbox doesn't neutralize timing side channels. It just changes where they live.
WASM as a malware delivery mechanism
WASM modules can contain fully functional malware. The browser sandbox constrains what they can do to the host operating system, but within the browser they have access to all JavaScript APIs, cookies, local storage, the DOM, and network requests. The first widely-deployed WASM malware was cryptominers: compressed WASM modules with obfuscated code running Monero mining algorithms silently in visitor browsers.
The binary format is the real advantage for attackers. WASM bytecode is obfuscatable in ways that differ from JavaScript, and the deobfuscation tools for WASM are less mature than their JavaScript equivalents. Documented in the wild: WASM-based keyloggers hooking DOM events, click-fraud bots running in Web Workers, credential-harvesting modules in compromised CMS plugins, and WASM loaders whose primary function is to download and evaluate JavaScript payloads or decrypt embedded shellcode.
The loader pattern is worth noting. The WASM module itself looks benign in static analysis. The malicious payload is downloaded and executed separately. This splits the malware across two files and makes analyzing the WASM module alone insufficient. A security scanner that only looks at the WASM binary misses the actual attack.
WASI brings server-side capability gates, and new failure modes
WASI extends WASM to server-side execution with a capability model: a module only has access to host resources explicitly granted by the host process. File system access is capability-gated. Network access requires an explicit socket capability. This is a strong security property when used correctly.
The failure modes are familiar from cloud IAM: overly permissive capability grants (giving a module access to the entire file system when it needs one directory), bugs in the WASM runtime itself (Wasmtime has had several security-relevant CVEs), and supply chain risks in the WASM module being executed. The capability model doesn't help if you grant every capability by default. It also doesn't help if the runtime implementing the capability checks has a vulnerability.
Teams deploying WASI modules on edge functions or as server-side plugins need to audit capability grants with the same rigor they apply to IAM policies. The attack surface is smaller than running native code, but it is not zero.
Defenses that actually work
Content Security Policy for WASM uses the wasm-unsafe-eval directive to control dynamic compilation. If your application doesn't compile WASM dynamically, exclude this source. For known WASM modules, use subresource integrity attributes with the module's hash to prevent a compromised CDN from serving a modified binary.
WASM module scanning is available through tools like wasm-decompile and the Binaryen toolchain, which can decompile WASM to readable intermediate representation for static analysis. Commercial WAF and bot detection products offer automated scanning for known cryptomining patterns and obfuscation techniques.
For C and C++ compiled to WASM, enable AddressSanitizer in development and use safe stack with stack canaries in production builds. Emscripten supports both. For WASI deployments, grant the minimum set of capabilities required and audit those grants as carefully as you audit IAM policies. The isolation guarantees in WASM are real. The risks are in misunderstanding what the sandbox protects against and what it doesn't.