3 ms·
Type confusion is also a very common attack against JS runtimes and V8 specifically. Of course, it's not trivial to build a high-performance JS runtime without
by kevingadd 3y ago
Type confusion is also a very common attack against JS runtimes and V8 specifically. Of course, it's not trivial to build a high-performance JS runtime without playing around with pointer types pretty liberally, so I can understand saying "Rust won't fix this" in regards to those attacks.
But those attacks would basically not be possible against a runtime built on top of Java or C#.
- sroussey 3y agoThe attacks would not be possible against a runtime written in JavaScript as well, by that reasoning.
- olliej 3y agoYes because the attack would be against the .net or Java VM. The JVM - especially in the era of applets - had an illustrious history of VM bugs. We don’t know how bad they would have been because in the era of extremely complex exploits applets essentially do no exist. Neither .net nor the jvm are exposed to the degree of attacks the js engines are, and there’s no strong reason to believe they don’t have similar bugs today.
- kevingadd 3y agoI'm not singing the praises of the JVM here, it's just a simple fact that if you implement your runtime in a higher level language you're exposed to a smaller number of potential vulnerabilities. Unchecked array dereferences turn into bounds-checked array dereferences; unchecked typecasts turn into checked typecasts. Null pointer dereferences turn into null reference exceptions. Etc. Of course once you start jitting native code, all of that is off the table. Unless you jit to java/.net bytecode, I guess.
- olliej 3y agoNo, 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.
- kevingadd 3y agoPeople have previously shipped JS runtimes on top of .NET and the JVM. It's not a question of 'who writes the GC', it's more fundamental. 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.
- vlovich123 3y agoWould be interesting if they took hardening ideas from kernels that try to solve this (e.g. https://security.apple.com/blog/towards-the-next-generation-of-xnu-memory-safety/ https://security.apple.com/blog/towards-the-next-generation-...).
- ngrilly 3y agoV8 is a runtime for JS exactly like the JVM is a runtime for Java and CLR is for C#. Which means that whatever sandboxing V8 needs, the JVM and the CLR would need it as well. I don't know what makes you think that the JVM and the CLR have already solved the problem, but not V8.