My sibling comment is correct; the only way this can happen is an interpreter bug. Bugs happen, but they can happen in JS too. I think you’re assuming things the spec doesn’t allow.
"Controls your account" is possible without ever exploiting an interpreter bug or escaping the sandbox. Your account credentials are usually available inside the current tab.
The example I gave in another comment holds here: Let's say I want to load PNGs and I'm fed up with color profile bugs in browsers' image decoders (sigh...) so I decide to compile a known-good build of libpng or stb_image with wasm. Now someone finds a png decoder exploit that works against my build. If I'm not cautious about my imports, they can escalate privilege out of my wasm library and then take control over my gmail.
Ideally wasm libraries will always be narrowly scoped and good about what they import, but there will definitely be broadly scoped libraries that import a ton of dangerous stuff, and there will be some that import a function that is effectively eval because they don't want to declare a thousand imports by hand.
It's certainly possible for JS libraries to have these kinds of vulnerabilities, but it's hard for me to imagine how a JS PNG decoder would end up with the same sort of attack possible on it since it's parsing binary data into pixel buffers. At worst, you'd crash it.
Yeah, sorry about the duplication here, I'm extremely interested in this specific topic.
> Now someone finds a png decoder exploit that works against my build.
I think this is the part I don't get. Specifically, how would an exploit work within wasm? That is, in the wasm environment is different than in native; the memory is bounds checked, for example. Basically, I 100% agree that some security bugs are logic bugs, but take the above stack smash, for example: that can't happen, in my understanding. Again, modulo interpreter bugs, like any sandboxing technique.
> it's hard for me to imagine how a JS PNG decoder would end up with the same sort of attack possible on it since it's parsing binary data into pixel buffers. At worst, you'd crash it.
It's hard for me to imagine how wasm is any different than JS here.
How does wasm stop stack smashes? I can see that if it's not a von Neumann machine i.e. code is in a different memory space to data, it'd be harder, but that doesn't seem really compatible with C/C++?
Just in general if I have an arbitrary memory write primitive inside the wasm memory space, how much control over the program can I obtain?
wasm does some stack isolation so that the function's local stack variables are not next to things like the return value in memory and loads to/from stack slots are special instructions that reference slot identifiers. Most stack operations aren't arbitrary memory reads/writes from addresses so it's not possible to overflow them and corrupt other values.
The caveat is that not everything native apps put on the stack can currently be stored in wasm's safe stack, so applications often put a secondary stack inside their heap. This will also happen if you're - for example - passing large structs around as arguments. You can smash the heap stack if you manage to find an exploit, and if function pointers or other important data are stored there, you can turn that into an attack.
It's absolutely the case that a large subset of stack smashing attacks don't work on wasm, because of the safety properties. Some of them will still work though. The way function pointers work in wasm raises the risk profile a bit if you manage to get control over the value of a function pointer, since function pointer values are extremely easy to predict.