3 ms·
How does Apple's security model allow for any malformed web page to execute arbitrary code?
by fortran77 4y ago
How does Apple's security model allow for any malformed web page to execute arbitrary code?
- henriquez 4y agoThe malformed [anything] to run unsigned code is an age old bug archetype. This is the obvious result of web browsers providing OS-level API access to JavaScript web pages.
- Gigachad 4y agoBecause WebKit is written in C so malformed anything has the ability to run arbitrary code. As far as I know there is no current work being done to fix this. Google has been making significant efforts to replace insecure C components in Android with Rust though.
- asddubs 4y agoIt's written in C++
- astrange 4y agoWebKit is largely a JIT and a JIT is itself unsafe, so writing one in Rust won't help. ARM has been adding security features that do help with any language like PAC/BTI.
- nneonneo 4y agoA JIT is not, by itself, unsafe. The problem is that maintaining the complex set of constraints and invariants necessary to generate both safe and performant code is extremely difficult, and one slip-up can mean generating code that breaks some invariant and escapes a safety boundary. You can have simple JITs that are completely safe: they generate code to bounds- and type-check unconditionally and avoid fragile optimizations. But, if you want to go faster, you have to start dropping checks and performing aggressive optimizations (peephole, inlining, object layout tricks, …) and every new optimization is an opportunity to make a mistake. PAC and friends are an effort to make the hardware support certain checks more efficiently. But again, as they are an extra check, there’s always the chance that they’ll be slower than the unchecked alternative; if so, you can bet that one day an engineer looking to get a 0.5% perf gain will try removing those checks (“safely”) and we’ll be back to square one.
- astrange 4y ago> A JIT is not, by itself, unsafe. The problem is that maintaining the complex set of constraints and invariants necessary to generate both safe and performant code is extremely difficult, and one slip-up can mean generating code that breaks some invariant and escapes a safety boundary. I mean… isn't that what unsafe means? A "memory-unsafe" language means a language it's possible to make a mistake in, not one where memory errors happen all the time.
- nneonneo 4y agoThe statement that a JIT is itself unsafe is tantamount really to saying that “compilers are unsafe” or even “interpreters are unsafe”. All a JIT really is is a way to execute code. As an example, the Rust compiler has some [60+ open unsoundness bugs](https://github.com/rust-lang/rust/labels/I-unsound https://github.com/rust-lang/rust/labels/I-unsound), meaning that there are many, many ways that a sequence of ostensibly safe code could be compiled into an unsafe executable (i.e. one which exhibits an unsafe behaviour like a double free). If you allowed malicious users to run Rust code on your machine, even without unsafe features and a limited standard library (as the case with JS in the browser), they could take advantage of these compiler bugs to escape Rust’s safety guarantees and whatever protections you put in place. And these bugs exist even though Rust itself is a safe language, and even though much of the Rust compiler is itself written in a safe language.
- eyelidlessness 4y agoAs your current sibling comment points out, most vulnerabilities are in the JIT. It’s certainly possible to exploit the browser itself with unsafe code it may be running, but a lot more probable that exploits take advantage of the runtime compiler(s) hosted by it. Rewriting even all of WebKit in Rust might benefit at the JIT level but it very well may not, because ultimately it’s still a hosted compiler for an arbitrary dynamic language.
- nneonneo 4y agoBreaking the JIT is just the first step for most browser exploits. The JIT lives in the renderer process, which is heavily sandboxed in modern browsers. To do anything useful, an exploit usually has to compromise the browser process with a second bug (“sandbox escape”). Rewriting the browser part in e.g. Rust would be a great step towards closing off that avenue of attack.
- kitsunesoba 4y agoI wouldn’t be surprised if significant chunks of WebKit start getting rewritten in Swift once it gains C++ interop. Not that use of Rust is impossible but so far Apple’s interest in Rust has been as far as I know entirely in server usage.
- nneonneo 4y agoA common approach is that there is a bug in the JavaScript engine (most often a bug in the JIT) which makes it possible for a bit of nasty JS code to start executing arbitrary native code inside the browser tab. This can, for example, involve corrupting the memory of a JavaScript object, gaining read/write access to the heap, and then further corrupting e.g. C++ virtual function tables to redirect control flow execution. This gives the attacker control over the “renderer” process that handles the webpage inside a secured sandbox. So, the attacker has to then exploit the sandbox itself to gain more permissions. The renderer communicates with the parent browser process over IPC, and there are a lot of objects and communications channels between the two. So, a second bug in the browser process can be exploited by the (compromised) renderer process via IPC. Once successful, the attacker has full control over the browser and can do anything the browser can. Sometimes this is enough for the attacker; other times, they might exploit a third bug in the OS kernel to gain root access and thoroughly own your phone.