Popping an alert from a sandboxed WebAssembly module

Would you believe me if I told you this HTML page could show an alert('hi from WASM'), when loaded?

<script>
WebAssembly.instantiateStreaming(fetch("plugin.wasm"), {});
</script>

More generally, if plugin.wasm is attacker-controlled, this could execute arbitrary JavaScript, despite the empty object as imports! Doesn’t this feel counter-intuitive, given the isolation properties of WebAssembly?

It turns out that the WASM/JS barrier is not really meant to be a sandbox, and that a subtle “feature, not a bug” in the WebAssembly JS API specification allows for such an “escape”, when making use of some convoluted JS prototype and WASM interop trickery.

Phrack article

The full details of the trickery in question are explained in an article I wrote for Phrack 72:
https://phrack.org/issues/72/10_md#article

Talk

If you’re more video-oriented, I also gave a talk about this technique at WHY2025 which was recorded:

Escaping a misleading “sandbox”: breaking the WebAssembly-JavaScript barrier (WHY2025).