5 ms·
My intuition is that the answer is "uhh, no." -- is there any secure way to run untrusted javascript on a page? So that we could have those awesome newgrounds s
by MrLeap 5y ago
My intuition is that the answer is "uhh, no." -- is there any secure way to run untrusted javascript on a page? So that we could have those awesome newgrounds style wildwest galleries where people upload their weirdsies again. I've seen some synthetic namespace shenanigans that I've had a hard time breaking out of, but nothing that makes me comfortable.
I know Flash never had a reputation for.. security, but Youtube-for-html5 games seems like it could never exist for my intuition. I'm sure you could get away with it on small scales, but anything beyond a person's ability to curate and we go backwards.
- derefr 5y agoThe thing that would guarantee this, isn’t limiting the runtime (because you’ll always miss something, or be incapable of fully masking out something), but rather static analysis of the code to ensure it doesn’t attempt to use any of the dangerous features in the first place. It’s very hard to static-analyze JavaScript, of course, because it’s all late bound with a reflective runtime — you can get access to anything by building the right identifiers out of strings and then subscripting using them. WASM doesn’t have that same problem, though. It’s very easy to static-analyze bytecode-encoded WASM (as long as you don’t want “requiring modules from external URLs” to be a part of your Newgrounds-alike platform’s runtime surface.) It’d be pretty safe to have a site that hosts arbitrary untrusted static-analyzed-subset-of-WASM.
- johncolanduoni 5y agoWASM doesn’t need any sort of “static analysis” to sandbox it in this way. WASM only gets to call the functions exposed by the script that loads the WASM, so if you don’t want it to access something you can simply not bother exposing it.
- derefr 5y agoYes and no. There are capabilities that you can only either expose to WASM or not, because they’re simple atomic functions in Javascript land. Dereferencing external Javascript-side objects by a passed-through key, for example. You could in theory write a “fat ISA-op emulation-shim implementation” for that WASM-side operation that has a bunch of Javascript verification code that runs every time the WASM-side op is called, at runtime (like how the Ethereum VM has fat ISA-ops that spend gas/check remaining gas in their impls.) But the resulting runtime likely won’t be performant enough to be a good host for games, if the games make heavy use of that capability, rather than just using it as a one-off boot-time thing. Remember, we want to mostly allow arbitrary code execution here—other than direct attacks on the user or the hosting infrastructure. That probably means that we want to allow the user of the WASM to require (a pre-approved set of) Javascript-side libraries and talk to them. For example, maybe the game wants to talk to Firebase using the Firebase SDK. It should be able to do that. But how do you allow the game’s WASM to talk to the Firebase SDK, efficiently, without allowing the game’s WASM to manipulate the objects of the Firebase SDK into giving it ACE in the host JS environment, outside its sandbox? Static analysis. For the case of a “dereference a key of an remote object” call, just validate that: 1. The string being used as the key in the dereference op is known at compile time (i.e. the dataflow digraph terminating in the WASM “syscall” to the runtime, begins with a load from the static data section of the WASM file; 2. The static-loaded string you discover through this method, isn’t on a blacklist of ECMAScript system properties. (If you want to do something that requires one of those, there’d have to be a separate, much-more-restricted syscall for that, maybe one that does have a fat impl.) The nice thing about this approach, is that it’s the server backend, not the players, who feel the sting of the overhead of checking the file for safety; and then, only once per uploaded program. It’s like putting the uploaded games into a moderation queue, where the “moderator” is a robot with good eyes to spot evil code.
- johncolanduoni 5y agoLast time I checked, all the abilities for directly manipulating JS reference types in WASM had yet to even be deployed outside of developer trials. So there’s a much simpler solution that (a) doesn’t depend on “just” statically analyzing the binary and (b) doesn’t use features that most browsers don’t support. Just expose precisely the Firebase or whatever functionality you wish to through normal WASM imports. No overhead of checking the file for safety at all (beyond the built-in WASM validation and translation of course). And binding the functions for e.g. WebGL directly with a lookup table for passed in object values is going to perform as well as anything else that is actually supported today (and it’s what game engines that support WASM currently use).
- derefr 5y ago> Last time I checked, all the abilities for directly manipulating JS reference types in WASM had yet to even be deployed outside of developer trials. Well, yeah, which means to me that we'd never try to do this today, but rather would do this once that sort of capability exists. (Just like the people who constantly propose multitenant Workers-like hosting within Erlang. Obviously it could work once sandboxing exists within the runtime, but that's not true today.) Note that the whole point of Firebase as a service/library—I picked this example for a reason—is to have a local live Javascript object graph whose state is synchronized over the network to a database somewhere; where you can walk it and read it and change it by doing regular Javascript things to it, as if it were a pure in-memory data structure. If you want to expose that in WASM, you basically need to expose it by exposing Javascript object manipulation semantics to WASM. (Not with WASM holding the objects itself, but rather like any "remote/distributed object" protocol, where WASM holds a handle that references an object, and makes syscalls for dereferencing-get, dereferencing-set, etc., passing that handle.) Without this, what you're exposing isn't really "Firebase" per se, but just a regular database that you send some sort of graph-manipulation queries to. And this is just one example among many of the sorts of arcane Javascript things where, if the hosting platform didn't allow them, then devs would find the hosting platform worthless and never engage with it. This is the whole point of the GGP poster's post. They weren't talking about sandboxing NaCl/ZeroVM-like "the code runs in a sealed ABI abstraction that only exposes the syscalls necessary to read the keyboard/mouse and draw to the screen" games. You can easily do that. It's been done. Developers didn't engage in any meaningful way—nothing like the takeup of Newgrounds. (Heck, it's downright simple to do one of these services yourself: pick an old game console with an HTML5 emulator implementation, e.g. one of the ones used on https://archive.org/details/internetarcade https://archive.org/details/internetarcade, as your abstract-machine runtime. Games, then, are arbitrary homebrew ROMs. Let people upload them; give them a customizable page that embeds them; wrap it in a trailer + payment-wall page ala itch.io if you like. Do fingerprint analysis to reject commercial ROMs. Done. This service could be built for a hackathon. Would anyone care to develop novel games for it? Pretty doubtful.) Instead, what the GGP was talking about sandboxing, is almost-but-not-quite arbitrary Turing machines. Because that's what the Flash games/apps posted to Newgrounds really were, and moreover what the modern track-every-click special-gatcha-for-the-thousandth-player-of-the-day variety always are. They use every capability a computer has, such that "sandboxing" in the sense of removing those capabilities doesn't make sense. You can't restrict what capabilities such programs have access to, without just denying the entire design the software is based around. You can only constrain how the game uses those capabilities. To put that another way: an SMTP server that doesn't let you send mail to certain large email hosting providers is effectively useless. But an SMTP server that doesn't let outgoing messages contain certain words (i.e. has an outbound spam filter) is quite useful. Restricting the what will just turn people away. Restricting the how has no such problem, since certain patterns of data-flow have no other use than to be nefarious. (If you're curious why I'm even talking about WASM at all, then, if I'm not proposing to take advantage of any of the sandboxing WASM offers: it's just because it's much easier to do your static analysis against a symbolic-execution implementation of bytecode VM for a bytecode ISA like WASM; than it is to do symbolic-execution of an interpreted language with complex syntax, like JS. But if you were willing to go down that route, you could totally static-analyze regular JS. Same safety guarantees, plus now the devs get to use regular JS and/or anything that interfaces with it—including the JS-subset textual form of WASM.)
- johncolanduoni 5y agoThe iframe sandboxing feature is better suited for this. It puts the full strength of the same-origin security policies of the browser between third party content and first party content on a domain. It has “only” been around since IE 10 or so though so it wouldn’t cover all of the golden age of flash. It’s worth noting that Flash was actually quite hard to contain from interfering with your origin, and the main defense against this was that there were no sensitive APIs, cookies, or local data on the domains the flash was hosted from anyway.
- MrLeap 5y agoAh yeah that's a good idea. Assuming there's no reasonable way to do an iframe breakout, that is. I suspect any way I attempted to put this together, ner-do-wells would upload a game that adds upvote/like/subscribe/logout to every event handler. Now that I think about it, I can't remember any reason why I wouldn't be able to do that from inside actionscript.. I ran javascript from inside flash all the time.. The fact those flash sites didn't just unravel from shenanigans is pretty astounding in retrospect.
- currysausage 5y agoThere was ADsafe by Douglas Crockford [1], but it looks rather abandoned [2]. There's also Caja by Google [3], but that is abandoned too. [1] https://www.crockford.com/adsafe/index.html https://www.crockford.com/adsafe/index.html [2] https://github.com/douglascrockford/ADsafe https://github.com/douglascrockford/ADsafe [3] https://developers.google.com/caja https://developers.google.com/caja