Hacker News new | ask | show | jobs
by standupstandup 3130 days ago
Well, WebAssembly's primary near term contribution will be introducing the world of C++ exploits to web apps, which are already groaning under the load of XSS, XSRF, path traversal, SSRF etc attacks. Adding double frees, use after frees and buffer overflows on top doesn't seem ideal.

As for the rest, well, it'd be nice if there was any sort of plan to make Blink safer. I know about oilpan but what Mozilla is doing with Rust is impressive. The JVM guys are working on rewriting the JVM in Java. What's Blink's plan to make its own code safer? Sandboxing alone?

2 comments

Microsoft is also taking steps to incrementally rewrite .NET runtime in C#.

https://www.infoq.com/articles/virtual-panel-dotnet-future

And the D guys have been rewriting dmd, the reference compiler, into D.

What exploits are you specifically worried about with wasm?

The ones you call out in this post don’t have the same impact as native, even when it’s C or C++ compiled to wasm.

http://foo.bar.com/url?q=<base64 encoded stuff>

wasm program parses q

stack smash occurs

ROP chain is used to gain code execution

user cookie is stolen

attacker now controls your account

I don't know enough about wasm to know if it has some special mitigations for this but when I looked at it, wasm seemed closer to a CPU emulation than a high level language VM. Flat memory space, no GC, no pointer maps.

WASM memory is a set of memory specific to a module (and they only allow one memory instance right now). It can be imported/exported to other modules, but there is no sandbox escape (in theory). For the web backend, it's just backed by a UInt8Array IIRC. It's all userland. If anything escapes the WASM interpreter/compiler, it is the fault of the interpreter/compiler (as is the case here) and not the fault of the WASM bytecode itself which has no escape mechanism. Think of a WASM VM just like a JS VM. Even though it may appear low level just because it can JIT better/cleaner, it operates in the same arena as JIT'd JS (at least for the web target).
You don't need to escape a sandbox when the application has access to all the user's data.

The attack surface of a gmail implemented in C++-compiled-to-wasm is almost certainly going to be larger than a gmail implemented in JS, because the runtime environment is vulnerable to double frees and heap corruption and other attacks, even if it won't escape the browser sandbox. My gmail tab basically has access to my entire life.

I don't understand. In the gmail example, the attack surface to who, a malicious email sender? As in something being handled by wasm in the browser has a better chance at XSS than if it was handled with JS? Why would untrusted content like that be handled by a client-side language anyways? Whether it is wasm, JS, wasm-interpreted-by-a-JS-interpreter, JS-interpreted-by-a-c++-intrpreter, wasm-interpreted-by-a-c++-interpreter or whatever the risks are similar. If you are talking about untrusted wasm or JS scripts accessing things inside the same sandbox, that's a different vector and it's less about the size of surface area and more about the introduction of the vector in the first place.
Simple example (though not something I think the Gmail team would actually ship): I want to load a .png file that's attached to an email. If I decide to use a build of libpng I control (for example, to work around broken color profile support in browsers), a bug in that libpng build could allow privilege escalation within the tab to get access to my gmail contacts or send emails. Bugs in loaders for image file formats are not unheard of, and people treat image files as innocuous.
WASM resulted in adding a lot of new API to JS, like thread-shared buffers and coming atomics. This requires quite a few new lines of native code in the implementation significantly increasing attack surface. Another thing is that WASM makes code faster so exploiting timing bugs or cache leaks gets easier.
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.
I’m not sure what you mean, specifically, here. Or at least, how wasm is somehow worse than JavaScript in this regard, which is the baseline here.

In fact, it should be better, given the static declaration of external calls that can be inspected.

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.