|
|
|
|
|
by olliej
810 days ago
|
|
No, you're missing the point. The whole point is you're implementing the runtime that defines the safety semantics. Your proposal is essentially "implement your JS engine GC on top of the JVM by just using the JVM's GC", i.e. don't implement the GC yourself. The unsafe code is now the JVM GC, and you've just moved the problem from "implement the JS engine's GC" to "Implement the JVM's GC", and they same problems continue to exist. I am really struggling to understand where this gap in understanding is occurring. It does not matter what environment or language you implement a JS engine (or whatever) in. The attacker is going to attack the unsafe portion of the runtime. If you build you JS engine on top of the JVM, then the attacker is not going to attack your JS engine's runtime, they attack the JVM's. The JVM, .NET, etc runtimes are not doing anything different to what the JS engine runtimes are doing, and aren't magically free of the same bugs. If anything they're probably doing less to protect from or prevent attacks, because they have a much much smaller attack surface (because they aren't generally exposed to everything on the internet) and the reason attackers have to target the JS engine runtime is because the JS sandbox does not allow the general system access "correct" and completely uncompromised .NET or JVM code have. Attacks on the JVM and .NET generally mean "convince the VM to load correct code that does something that a specific app/service is not meant to do but the VM generally allows applications to do", whereas a JS VM does not allow an attacker to do anything outside of the JS sandbox, so they must compromise the runtime. It may be easier to understand if we try to present this in a different way: JSC can be compiled as an interpreter for any cpu architecture because there is a fall back C backend for the interpreter code generator, so you can compile JSC to WASM. Then you could make a version of webkit than executed all JS through the WASM build of JSC running under the native JSC runtime. You've now built your JS engine on top of a safe runtime (WASM), but it should hopefully be obvious that an attacker is simply going to continue targeting the native JSC runtime. |
|
If you JIT your JavaScript down into raw native code that bangs rocks together to dereference pointers, you need to make sure your generated code handles pointers correctly. You need to make sure to get all your bounds checks right, etc.
Sure, the JVM could somehow have a 30-year-old bug in its array bounds checks. But if you're JITing javascript to an IR that doesn't have raw pointers and instead uses strongly-typed object references and bounds-checked arrays, you have automatically closed off a whole category of defects. At the point where you're saying "sure, but what if the JVM messes up array bounds checks?" you might as well be asking whether v8 can really afford to rely on read-only pages and guard pages for its security sandbox. What if the kernel is broken?
I mentioned type confusion attacks in particular because they're a class of attack that generally doesn't work against java or .net applications because values can't change type arbitrarily during execution. Local variables and parameters have known types, object type casts are checked, array elements are typechecked before being stored, etc. Obviously you pay a cost for this, and if you have threads the ABA problem rears its head, but JS is single-threaded by design.
Between hosting JS on the JVM or in WASM, WASM is probably a safer choice since it's such a constrained sandbox. But the JS runtime you're running inside of the WASM sandbox is still built in C, banging rocks together to dereference pointers. Hopefully you're running a modern security-hardened JS runtime inside that sandbox, and you haven't turned off all the security mitigations thanks to wasm's lack of page protections.