7 ms·
I know one of WebAssembly's biggest features by design is security / "sandbox". But I've always gotten confused with... it is secure because by default it can'
by MuffinFlavored 2y ago
I know one of WebAssembly's biggest features by design is security / "sandbox".
But I've always gotten confused with... it is secure because by default it can't do much.
I don't quite understand how to view WebAssembly. You write in one language, it compiles things like basic math (nothing with network or filesystem) to another and it runs in an interpreter.
I feel like I have a severe lack/misunderstanding. There's a ton of hype for years, lots of investment... but it isn't like any case where you want to add Lua to an app you can add WebAssembly/vice versa?
- jeroenhd 2y agoWebAssembly can communicate through buffers. WebAssembly can also import foreign functions (Javascript functions in the browser). You can get output by reading the buffer at the end of execution/when receiving callbacks. So, for instance, you pass a few frames worth of buffers to WASM, WASM renders pixels into the buffers, calls a callback, and the Javascript reads data from the buffer (sending it to a <canvas> or similar). The benefit of WASM is that it can't be very malicious by itself. It requires the runtime to provide it with exported functions and callbacks to do any file I/O, network I/O, or spawning new tasks. Lua and similar tools can go deep into the runtime they exist in, altering system state and messing with system memory if they want to, while WASM can only interact with the specific API surface you provide it. That makes WASM less powerful, but more predictable, and in my opinion better for building integrations with as there is no risk of internal APIs being accessed (that you will be blamed for if they break in an update).
- panic 2y agoI don’t believe it is currently possible for a WebAssembly instance to access any buffer other than its own memory. You have to copy data in and out.
- deathanatos 2y agoThe embedder could hand the module functions for manipulating external buffers via externrefs. (I'm not sure if that's a good idea, or not, just that it could.) But if the module wants to compute on the values in the buffer, at some level it would have to copy the data in/out.
- davexunit 2y agoUse the GC instructions and you can freely share heap references amongst other modules and the host.
- panic 2y agoHow do you access the contents of a heap reference from JavaScript in order to “send it to a <canvas> or similar”?
- davexunit 2y agoAssuming you're talking about reading binary data like (array i8), the GC MVP doesn't have a great answer right now. Have to call back into wasm to read the bytes. Something for the group to address in future proposals. Sharing between wasm modules is better right now.
- brabel 2y ago> Lua and similar tools can go deep into the runtime they exist in, altering system state and messing with system memory if they want to That's not correct, when you embed Lua you can choose which APIs are available, to make the full stdlib available you must explicitly call `luaL_openlibs` [1]. [1] https://www.lua.org/manual/5.3/manual.html#luaL_openlibs https://www.lua.org/manual/5.3/manual.html#luaL_openlibs
- westurner 2y agoWASI Preview 1 and WASI Preview 2 can do file and network I/O IIUC. Re: tty support in container2wasm and fixed 80x25 due to lack of SIGWINCH support in WASI Preview 1: https://github.com/ktock/container2wasm/issues/146 https://github.com/ktock/container2wasm/issues/146 The File System Access API requires granting each app access to each folder. jupyterlab-filesystem-access only works with Chromium based browsers, because FF doesn't support the File System Access API: https://github.com/jupyterlab-contrib/jupyterlab-filesystem-access https://github.com/jupyterlab-contrib/jupyterlab-filesystem-... The File System Access API is useful for opening a local .ipynb and .csv with JupyterLite, which builds CPython for WASM as Pyodide. There is a "Direct Sockets API in Chrome 131" but not in FF; so WebRTC and WebSocket relaying is unnecessary for WASM apps like WebVM: https://news.ycombinator.com/item?id=42029188 https://news.ycombinator.com/item?id=42029188
- westurner 2y agoWASI Preview 2: https://github.com/WebAssembly/WASI/blob/main/wasip2/README.md https://github.com/WebAssembly/WASI/blob/main/wasip2/README.... : > wasi-io, wasi-clocks, wasi-random, wasi-filesystem, wasi-sockets, wasi-cli, wasi-http
- Karellen 2y ago> You write in one language Not quite. Web assembly isn't a source language, it's a compiler target. So you should be able to write in C, Rust, Fortran, or Lua and compile any of those to WebAssembly. Except that WebAssembly is a cross-platform assembly language/machine code which is very similar to the native machine code of many/most contemporary CPUs. This means a WebAssembly interpreter can be very straightforward, and could often translate one WebAssembly instruction to one native CPU instruction. Or rather, it can compile a stream of WebAssembly instructions almost one-to-one to native CPU instructions, which it can then execute directly.
- whizzter 2y agoA JIT should be able to translate most arithmetic and binary instructions to single-opcodes, however anything involving memory and functions calls needs safety checks that becomes multi-instruction. branches could mostly be direct _unless_ the runtime has any kind of metering (it should) to stop eternal loops (if it also wants to be crash-safe even if it's exploit safe).
- kouteiheika 2y ago> anything involving memory [..] needs safety checks that becomes multi-instruction Not necessarily; on AMD64 you can do memory accesses in a single instruction relatively easily by using the CPU's paging machinery for safety checks plus some clever use of address space. > branches could mostly be direct _unless_ the runtime has any kind of metering (it should) to stop eternal loops Even with metering the branches would be direct, you'd just insert the metering code at the start of each basic block (so that's two extra instructions at the start of each basic block). Or did you mean something else?
- charleslmunger 2y agoMetering also doesn't require a branch if you implement it with page faults. See "Implicit suspend checks" in https://android-developers.googleblog.com/2023/11/the-secret-to-androids-improved-memory-latest-android-runtime-update.html?m=1 https://android-developers.googleblog.com/2023/11/the-secret...
- pdubroy 2y agoYou should check out the book :-) We have a chapter called "What Makes WebAssembly Safe?" which covers the details. You can get a sneak peek here: https://bsky.app/profile/wasmgroundup.com/post/3lh2e4eiwnm2p https://bsky.app/profile/wasmgroundup.com/post/3lh2e4eiwnm2p
- coliveira 2y agoI think the biggest advantage of wasm in terms of security is that it doesn't accept machine language written in the target machine, only in this artificial machine language. This means that it cannot encode arbitrary code that could be executed by the host machine. Everything it runs has necessarily to go through the wasm interpreter.
- hb-robo 2y agoThat's quite interesting. This is way outside of my wheelhouse - has this kind of approach been tried in other security contexts before? What would you even call that, virtualization?
- wyldfire 2y ago> This means that it cannot encode arbitrary code that could be executed by the host machine. But the host machine still can, so it's not as big of advantage in that regard. If you could somehow deliver a payload of native code and jump to it, it'd work just fine. But the security you get is the fact that it's really hard to do that because there's no wasm instructions to jump to arbitrary memory locations (even if all the host ISAs do have those). Having a VM alone doesn't provide security against attacks. It's often the case that VMs are used with memory-safe languages and those languages' runtime bounds checks and other features are what gives them safety moreso than their VM. In fact, most bytecode languages provide a JIT (including some wasm deployments) so you're actually running native code regardless.
- Gupta2 2y agoSpeaking of WebAssembly security, is it vulnerable to Spectre/CPU style attacks like those in JavaScript? (WASM without imported JS functions)
- saagarjha 2y agoYes.
- jeffparsons 2y agoYes, if you give the Wasm instance access to timers.
- pizlonator 2y ago> But I've always gotten confused with... it is secure because by default it can't do much. Yes. That’s a super accurate description. You’re not confused. > I don't quite understand how to view WebAssembly. You write in one language, it compiles things like basic math (nothing with network or filesystem) to another and it runs in an interpreter. Almost. Wasm is cheap to JIT compile and the resulting code is usually super efficient. Sometimes parity with native execution. > I feel like I have a severe lack/misunderstanding. There's a ton of hype for years, lots of investment... but it isn't like any case where you want to add Lua to an app you can add WebAssembly/vice versa? It’s definitely a case where the investment:utility ratio is high. ;-) Here’s the trade off between embedding Lua and embedding Wasm: - Both have the problem that they are only as secure as the API you expose to the guest program. If you expose `rm -rf /` to either Lua or Wasm, you’ll have a bad time. And it’s surprisingly difficult to convince yourself that you didn’t accidentally do that. Security is hard. - Wasm is faster than Lua. - Lua is a language for humans, no need for another language and compiler. That makes Lua a more natural choice for embedded scripting. - Lua is object oriented, garbage collected, and has a very principled story for how that gets exposed to the host in a safe way. Wasm source languages are usually not GC’d. That means that if you want to expose object oriented API to the guest program, then it’ll feel more natural to do that with Lua. - The wasm security model is dead simple and doesn’t (necessarily) rely on anything like GC, making it easier to convince yourself that the wasm implementation is free of security vulnerabilities. If you want a sandboxed execution environment then Wasm is better for that reason.
- jedisct1 2y agoIt's like JavaScript, Python or PHP. There are no pointers, only arrays, that cause the app to crash if it attempts to read out of the bounds.