10 ms·
Securing Firefox with WebAssembly
- bigato 7y agoif parts of the web browser start being shipped as wasm code, we will eventually reach the point where the web browser shipped to the user is only a wasm vm, and all the rest will be shipped as optional libraries or even downloaded on the fly. Even stuff like the html engine, the css, and the javascript. In that world, using the messy web standards evolved over time would be optional. The web browser would then become the universal virtual machine that the world seems to want it to be, instead of a browser. The web would be the app distribution system. One could for example, decide to write their site using tcl/tk. Implementing the wasm vm and its basic apis would be simpler in a new operating system. Because the way it is now, the web browser itself is more complex that writing a simple operating system. That hinders innovation in the Operating System space.
- allendoerfer 7y agoAll I can see is people wanting to use web-technologies to develop applications. So I would place my bet on the DOM/CSS evolving further and swallowing everything. JavaScript might get some contenders.
- pjmlp 7y ago50 years later the mainframes have won. Language environments and containers.
- foobiekr 7y agoBut ... in a lot of ways worse.
- marcosdumay 7y agoThey have been "winning" since they started losing. Our PCs are much more similar to 80's mainframes than to 80's PCs.
- bigato 7y agoGood point. That should probably be the case for the majority of generation who entered the programming world in the last 20 years, which is quite a lot of people. But yet, old farts like me may disagree.
- greggman3 7y agoThere's a HUGE way to go to get there and I don't believe we really ever will. OSes support every language, 100s of Input Method Editors, all the issues of left to right and more complex text rendering than English. Asking every webpage to provide all of that and to keep all of that up-to-date would be a huge loss for the web and app dev in general.
- swsieber 7y ago> Consequently, there are now around 40 high-level programming languages that support WebAssembly, including C and C++, Python, Go, Rust, Java, and PHP. Wasm is not a new language, but a portable, pre-compiled, cross-platform binary instruction set for a virtual machine that runs in the browser. https://blog.stackpath.com/webassembly/ https://blog.stackpath.com/webassembly/ It doesn't seem terribly unlikely. I don't think it's the goal, but it seems like a fairly likely outcome.
- Yizahi 7y agoYou should check this talk about JS and ASM :) https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript https://www.destroyallsoftware.com/talks/the-birth-and-death...
- edwintorok 7y agoExactly my thoughts when I first read of WASI: conceptually you could now have a WASI runtime ("OS") and an HTML.wasm potentially independently developed and swappable. And since WASI is a lot smaller surface, it is easier to audit, test, reimplement, etc.
- mwcampbell 7y ago> One could for example, decide to write their site using tcl/tk. Please, please don't do that. Tk is completely inaccessible to blind people via screen readers, and probably people with some other disabilities as well, on all platforms. Most toolkits written by people who decide to throw out those messy web standards would probably have the same problem.
- skybrian 7y agoThis is kind of neat but it's not clear how to think about what WebAssembly is doing, since the output is native code. I guess it's essentially a safe compiler for C++ code? For a language whose compiler already outputs safe binaries, this step would be redundant. It's not that easy to write a safe compiler though. Would a compile toolchain that uses WebAssembly for all compilation be useful?
- nikbackm 7y agoIt's not a safe compiler for C/C++, the compiled wasm code can still be compromised, it just cannot touch the rest of the process except indirectly via returned values.
- cogman10 7y agoAnd, to be clear, people could still do bad stuff with compromised WASM. The big difference is that the WASM sandbox significantly reduces the surface area of what bad stuff can be done. Today, a compromise in the browser means the attacker can do whatever the browser can do (which is usually a LOT). With the sandbox, a compromise can only really affect what the sandbox has available to it. That means, if your sandbox only exposes a single method which takes in a string and returns a string, the worst thing an attacker can do is return a malformed string. Of course, if you mishandle that returned string then bad stuff will happen but it's a far cry from the input string being able to potentially cause arbitrary code execution which installs a virus on your machine. To really do something evil you have to not only compromise the code running in WASM, you have to find a way to break out of WASM. That's a lot harder to do.
- pjmlp 7y agoWebAssembly still suffers from possible internal memory corruption , so it is only safe to the extent that the C++ standard library with bounds checking enabled gets used. Alternatively WASM could eventually support memory tagging like SPARC and ARMv8.
- zozbot234 7y ago
- jokoon 7y agoI'm still waiting for better toolchains. WASM is really the greatest thing, but it's lacking proper support from compilers. Binaryen seems like a beast to use. I don't really understand why WASM is not just supported natively directly by clang or gcc.
- tjelen 7y agoIsn't it already supported backend in LLVM? https://github.com/llvm/llvm-project/tree/master/llvm/lib/Target/WebAssembly https://github.com/llvm/llvm-project/tree/master/llvm/lib/Ta... I mean it is still under development but I think it is usable. Here's a quick intro I found some time ago: https://dassur.ma/things/c-to-webassembly/ https://dassur.ma/things/c-to-webassembly/
- froydnj 7y agoThe WASI tutorial for compiling C/Rust to wasm and running it has some useful information on this front: https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-tutorial.md https://github.com/bytecodealliance/wasmtime/blob/master/doc... We wouldn't have been able to put wasm in Firefox like this if there wasn't decent compiler/runtime support via the clang ecosystem.
- wahern 7y agoThat C code has a bug where the inner write loop writes the same portion of the buffer after a short write. The Rust code, by contrast, slurps up the entire file contents into a buffer before writing it out. If someone is going to write code that way why even bother with a low-level language? (This "memory is infinite" mentality is something I've noticed in other Rust projects, even major ones like mio.)
- sunfish 7y agoGood catch on that bug! I'll fix that. Beyond that, that file is just a simple example for showing how to work with the toolchain and the sandbox.
- 7y ago
- nwah1 7y agoThis kind of technique could also be applied to the parts of Firefox built with Rust, correct?
- rapsey 7y agoRust is memory safe. It does not need this treatment.
- azakai 7y agoIt would still be useful in that case as defense in depth. Specifically it could guard against compiler bugs, use of "unsafe", etc.
- stjohnswarts 7y agoIt could but Rust already solves the issues this is aiming to solve but with fewer steps. I don't know what Mozilla's policy is on adding Rust vs C++ for new features.
- pcwalton 7y agoIt's really great to see this work. Cutting down the amount of memory-unsafe code in the browser is an important ongoing goal. I'd love to do the same for our contenteditable implementation. The hard part here is to implement a DOM abstraction, because that code currently pokes at DOM objects directly and you can't safely do that across a wasm barrier. Once we've done that, though, Firefox's contenteditable implementation would become a cross-browser library, which opens up some interesting opportunities. We could use it in Servo, and authors could ship it on their Web pages if they want to ensure a consistent contenteditable experience across browsers.
- sroussey 7y agoIndeed, that’s an area of code that has had a history of strange per-browser-version differences, though better today than in the past.
- nicoburns 7y agoHow would this work? Isn't the content editable attribute magic so far as web code is concerned. You can't currently implement contenteditable in userspace, can you? I guess maybe you could make an attribute which just enables a flashing cursor, and then everything else could be done with DOM apis...
- pcwalton 7y agoWe might have to add some magic hooks into currently-internal parts of the browser, so the fidelity may not be 100% if contenteditable is shipped as part of content. It'd be an interesting experiment and might help to highlight gaps in the Web platform.
- PetahNZ 7y agoWell Google Docs editing is fully custom, including the selection and caret. So it must be possible.
- nicoburns 7y agoI believe Google Docs implements it's own text layout entirely from scratch. Sure, you can do that, but that's a lot of work, and it doesn't perform particularly well.
- est31 7y ago> but we’re performing the wasm to native code translation ahead of time, when Firefox itself is built. This might be an advantage for startup performance, but it's also a disadvantage performance wise as then you can't use all available features of the CPU. That's one of the advantages that wasm gives you. > we were often asked, “why do you even need this step? You could distribute the wasm code and compile it on-the-fly on the user’s machine when Firefox starts.” We could have done that, but that method requires the wasm code to be freshly compiled for every sandbox instance. Per-sandbox compiled code is unnecessary duplication in a world where every origin resides in a separate process. Android keeps an on-disk cache, performing native compilation at installation time, or at first startup after an OS update. One could have a similar cache for Firefox as well. Anyways, this stuff can be improved in the future as well. This doesn't change the fact a bit that it's an amazing and really great idea to improve safety of the browser. I love it!
- pjmlp 7y agoThat is the same approach used by the language environments on mainframes, Windows Store (MSIL cloud compiler), watchOS and a couple of other platforms, I would guess.
- deleted 7y ago[deleted]
- chrismorgan 7y ago> Android keeps an on-disk cache, performing native compilation at installation time, or at first startup after an OS update. If you’re describing what I think you’re describing, that was a Dalvik thing (Android 4.4 and earlier), which ART (Android 5 onwards) doesn’t do. I also found it a pain, because from time to time even when there hadn’t been an OS update or any other such change my phone would take three or four minutes longer to boot up as it decided it had to optimise all its packages. No idea whether that was a typical experience.
- est31 7y agoThe compile target of ART's dex2oat tool is actually native ELF code while Dalvik's dex2opt only created odex files, so the on-disk cache still exists. I've found sources that this is still done on app installation. On whether it's still done on OS updates, I couldn't find sources, but I guess your experiences mean that now OS updates don't trigger recompilations any more. Thanks for the pointer!
- deleted 7y ago[deleted]
- badsectoracula 7y agoLooks like eventually Wasm will become JVM and Firefox will become HotJava[0] :-P [0] https://en.wikipedia.org/wiki/HotJava https://en.wikipedia.org/wiki/HotJava
- pjmlp 7y agoHowever given the progress rate of the proposals, I guess we will have to wait about 5 more years at very least.
- imtringued 7y agoEvery single day I am thinking how the JVM could actually be a platform that is worth using in many situations. That day may come but certainly not within the next decade. No matter how well you optimize your code the JVM will ruin it and make it slower and consume more memory than necessary. Of course none of this matters in a world where your internal dashboard with single digit user counts is set to use 4GB RAM just "to be sure".
- saagarjha 7y ago> No matter how well you optimize your code the JVM will ruin it and make it slower and consume more memory than necessary. On the contrary, I for one enjoy the benefits that the JVM brings to my poorly-optimized bytecode produced by javac.
- eitland 7y ago> No matter how well you optimize your code the JVM will ruin it and make it slower and consume more memory than necessary. Maybe you are really good at this. But for a good chunk of software engineers AFAIK compiling Java to bytecode and running it on the JVM easily outperforms their optimized code performance wise in most cases. JVM and JDK writers (and the same people on the Dotnet side) aren't dimwits and their efforts over the last two decades are being applied every time we compile and run software on their platforms.
- beagle3 7y agoIt's very impressive that they can do it with existing libraries properly. Personally, if I had to design a solution for this problem, I would use the io_uring model - which would allow every part to reside in its own process and memory space.
- gok 7y agoI wonder how this would compare to compiling the sandboxed code with ASan and UBSan on
- earenndil 7y agoAfaik those make for a 2x performance hit. And they don't necessarily protect against buffer overflows; if you overflow out of data addressable from one pointer, but into data that's legally addressable from another pointer, that's still an issue, but it won't be caught.
- saagarjha 7y agoAddress sanitizer and undefined behavior sanitizer are not intended to be security mitigations; it's possible to get around them and now you have bad things happening in your process again.
- daxfohl 7y agoThe docs list WASI as currently experimental[1] and has missing features[2]. I understand how the sandboxing approach can add security, but if using experimental technology to enable this, doesn't it potentially open up more new holes than it closes? I'd love to hear more detail about what exact parts of WASI are used here, and what happens if you compile C code that targets a "rough edge" or "missing feature" of WASI by accident? [1] https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-overview.md https://github.com/bytecodealliance/wasmtime/blob/master/doc... [2] https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-intro.md https://github.com/bytecodealliance/wasmtime/blob/master/doc...
- afiori 7y agoExternal experimental tools are different than internal experimental tools. It would not be a good idea to do the same using a tool they have little control over, but in this case they have full control over cranelift (up to even feeling secure in using a different version)
- daxfohl 7y agoIs there any reason to continue using process-level sandboxing if this approach is available? It sounds like WASI adds an extra layer of security even beyond process-level sandboxing by being able to limit access to system resources. Or is access to system resources really not the concern here / can you do that just as easily with process-level sandboxing? And you can pass callback functions to sandboxes, which IDK if you can do with separate processes. Does process-level sandboxing provide any advantages WASI doesn't?
- TuringTest 7y agoThe sandbox architecture model makes me think of cell membranes. https://plsyssec.github.io/rlbox_sandboxing_api/sphinx/ https://plsyssec.github.io/rlbox_sandboxing_api/sphinx/