There's not a lot of context in this submission, but presumably it is being linked because the release notes for this CVE says "Google is aware of reports that an exploit for CVE-2024-0519 exists in the wild."
I'm pretty sure it isn't, the write up only uses 517 to get an arbitrary write primitive and then did a pretty standard chain into a sandbox escape via wasm (disclaimer - I work on V8).
Hmm. I also thought the type confusion in 518 was the same one from the blog post, but looking at the patch, it's not either. I think I stand corrected overall.
"We pride ourselves in our skillsets to parallel those of nation state hacking groups, and we tout that our expertise is unrivaled in our ability to discover and exploit vulnerabilities in a variety of product.
Our intention as a Company is to provide this intelligence to US and Allied countries for their enterprise and governments to have a leg up over the malicious actors from around the world."
What does trusted really mean? If you use node (or other JS packaging systems), you are running code that someone else wrote, that almost certainly you didn’t review as it’s huge, changing, etc. How about companies that use v8 to run JavaScript extensions to their app that their customers wrote. This is many apps. Are you saying they are all vulnerable?
The answer is they are all vulnerable, just because of problems like this. Any user code (js in this case) is untrustworthy, and everything has js extensions. What’s the safe way to run user JS? Running v8 in its own somehow separately limited process maybe is what I think people do.
Whether or not you review your deps code is on you, it doesn't make it untrusted. You're trusting them whether you do the due diligence to see if that trust is warranted or not. Untrusted means code that comes from outside your system, like 3rd party extensions to your app and is presumed to be completely broken and actively malicious and nonetheless shouldn't crash your own program or reveal sensitive data.
There is a massive difference between the supply chain risks of open source packages and actively fetching and executing remote code provided as user input like the browser inherently does.
The case of user provided extensions definitely falls a lot closer to the supply chain threat model.
I agree; "trusting" third-party/remote code or not frankly went out the window with the bathwater including baby when we moved on to Web "JavaShit" 2.0, or was it 3.0.
Feels like we're in a worse security hellhole than we ever were with Flash or ActiveX back in the day, frankly.
For context, assuming by JavaShit Web 3.0 you meant JavaScript:
Flash and ActiveX were proprietary technologies that often required users to install plugins or additional software on their devices. These plugins operated with high levels of access to the system, which made them a significant security risk. They were notorious for being frequently exploited by attackers as a way to run malicious code on users' machines.
In contrast, JavaScript is a core part of the web and is executed within the browser in a sandboxed environment. This means that JavaScript operates with limited access to the system's resources, reducing the risk of system-level security breaches.
> In contrast, JavaScript is a core part of the web and is executed within the browser in a sandboxed environment. This means that JavaScript operates with limited access to the system's resources, reducing the risk of system-level security breaches.
Flash (and probably ActiveX) were also executed in a "sandboxed environment", including "limited access to the system's resources". All 3 have (or well, had, in the case of Flash and ActiveX) regular vulnerabilities - including JavaScript. JavaScript is not any better than Flash or ActiveX and I really don't understand why people pretend it is.
BTW, Flash was definitely a core part of the web in its heyday, too.
ETA: Oh, and Java was also executed in a sandbox (and a virtual machine!) and had plenty of vulnerabilities back when applets were a thing.
At least with Flash, ActiveX, and Java you could choose not to install them and most sites would continue working. For JavaScript you have to install (and trust) some third party extension to block it and then no sites work...
Flash was never a core part of the web. That was the problem: it was loosely bolted onto browsers but the company behind it didn’t understand or care about the web, spent their time inventing random new things for demos trying to get you to build on top of their platform INSTEAD of the web, and was never willing to spend time on support.
> JavaScript is not any better than Flash or ActiveX and I really don't understand why people pretend it is.
Because it is. Both of those were hard to use without crashing the browser - the primary selling point for Chrome originally was that it used process sandboxing and so when Flash crashed you wouldn’t lose every open window - whereas what we’re seeing now are complex attacks requiring considerable investment finding ways to get around the layers of precautions. It’s like saying that there’s no difference between leaving your money under the mattress and putting it in the bank because banks still get robbed.
> That was most definitely not the primary selling point of Chrome.
It was very popular, especially for people who did support or were the “tech guy” for their friends & family. Chrome had multiple nice features but the one which most frequently got people to switch permanently was not losing all of your work when Flash crashed. Not having to tell people that the big comment they’d been working on for an hour was permanently gone because some ad in a different windows crashed Flash lead to a lot of installs.
This was especially bad for anyone developing in Flash because Adobe was motivated to sell licenses and only cared about reliability to the extent that it impacted sales. Their vision was that instead of using web technologies you’d target Flash and run things maybe on the web, desktops, mobile, or set top boxes but always Flash. The problem with that was that they mostly focused on shiny new things which demoed well but didn’t spend money on QA or support. I shipped a couple of Flash apps in the 2000s where we hit basic bugs in their library code, and the support process was basically that you filed a bug report with a ton of details, didn’t hear anything back until the next major release, and then the issue would be automatically closed with a generic suggestion that you try buying the new version and reporting if it wasn’t fixed. $800 later, you could repeat the process as they never once fixed a bug even with a simple reproducible test case.
Flash did things "web technologies" didn't. There was no module system, no React, no custom elements. JavaScript was a bit like bash: usable for simple things, but only masochists would use it for anything complex.
The early Google web properties - Maps and Gmail - were the vanguard of the web as an interactive platform. As I recall, they were actually written in Java and translated to JavaScript (by GWT) in part because of how limited JS was as a platform at the time.
To this day, there are things that's were easy in Flash that are borderline impossible on the web. The dual paradigm of drawing when drawing is easiest and coding when it isn't was really powerful, and the modern web still misses that.
I was thinking the other day of making a button that transitions into a throbber when you click it. Would have been a fun afternoon project in Flash. Would be a couple weeks of math homework in JS.
> As I recall, they were actually written in Java and translated to JavaScript (by GWT) in part because of how limited JS was as a platform at the time.
GWT - at least the opensource version - came a few years after Gmail launched. I’m pretty sure gmail and other Google products of that era were written using the Google Closure compiler. Not GWT. (Not to be confused with closure the language).
The closure compiler was written in Java, but it was a JS-to-JS compiler similar to a js bundler, minifier and the typescript compiler all rolled into one. Its input was (is) a semi-typed JavaScript dialect where types were put in special comments. It has a lot of code analysis & optimisation tricks that I think still aren’t present anywhere else in the JavaScript ecosystem. And it came with a batteries-included standard library that was really needed at the time, to both pave over browser differences and provide a lot of missing functionality. (Js was a scrapyard back then).
I’m surprised the closure compiler never saw much use outside of Google. It was a lovely piece of software for its time. It’s opensource - but nobody seems to know about it.
This is true. Especially before HTML5's canvas, video, and audio elements were standardized. Things have gotten so much better now with the advent of the Web Animation API also.
As powerful as Flash was though, sometimes that power was misused. I remember websites with slow intro animations that you had to wait to load before using the website. Flash also powered some of the most annoying advertisements I've ever had the displeasure of viewing.
Oh, sure, I wasn’t saying that Flash was entirely without value - we all used it for a reason - but simply that it wasn’t a web native technology. That proved to be its downfall: the entire ecosystem depended on the whims of a company which just isn’t interested in supporting platforms, and that proved to be fatal in the end.
That's a longer answer than I have scope to type right now…
The short version is the seamless interplay between drawn and coded objects. The viewport was called a Stage (Illustrator's equivalent is the Artboard). The Flash tool had all the vector drawing goodies you'd expect. Everything you drew on the Stage was a DisplayObject. Everything you coded was also a DisplayObject. Things that were easier to draw than code, you would create in the Flash app. Things that were parametric (e.g. you want 200 of them, or you want to explain in code how a thing moves), you'd code. You could easily import drawn assets into code, or drag visual containers for coded assets onto the Stage.
Modern JavaScript does an okay job at the coded aspect of it, but first class support for hand-drawn assets is totally missing. SVG (Adobe's attempt to compete with Flash before they bought it) can handle still images, but nothing is seamlessly multi-modal like Flash was.
The other thing Flash had going for it that nothing else does is animation. Even today, motion designers are stuck using After Effects (a tool designed for movie titles and broadcast news graphics). We still don't have a good tool for making interfaces that move, which means our ability to make properly interactive interfaces was severely knee-capped when Flash was removed.
So Flash let you draw and animate at whatever level of fidelity you wanted - draw an arm, animate a progress indicator - and use those assets seamlessly in code. Or code the parts that are painful to draw and lay everything out visually. It really let you use the best tool for the job, and it provided some best-in-class tools for those parts of the job that still aren't matched today.
PS: One of the coolest parts of Flash that nobody talks about was its ability to treat vectors like clay. Illustrator and the tools it inspired make you compose a vector out of points and bezier handles. Vector creation in those tools requires deft use of barely-abstracted math - it's a craft that's hard to master.
In Flash, on the other hand, you could just push and pull on the edge of a shape until it looked how you wanted. It abstracted the bezier into a more humane form, and that's just one of countless microtools that we lost when we lost Flash.
> The other thing Flash had going for it that nothing else does is animation. Even today, motion designers are stuck using After Effects (a tool designed for movie titles and broadcast news graphics). We still don't have a good tool for making interfaces that move, which means our ability to make properly interactive interfaces was severely knee-capped when Flash was removed.
We definitely need an easy to use GUI for building complex animations. Exporting animations from After Effects via Lottie is not an ideal solution. Maybe Rive or some other startup will fully supplant this workflow at some point.
Way too condescending and hyperbolic in turn, the general excuse being you believe the other post was hyperbolic. Even if the every assertion was 100% correct...D-. Revise and edit and please come see me after class.
> Flash (and probably ActiveX) were also executed in a "sandboxed environment", including "limited access to the system's resources".
IIRC, the main issue with ActiveX was that it did not execute in a sandboxed environment, unlike Flash and Java. With ActiveX, all you had was a cryptographic signature saying it came from a trusted publisher; past that, the full Win32 API was available, with complete access to the operating system.
That wouldn't particularly surprise me. I never used ActiveX, so I can't really speak to that one. But then, there also weren't many (public) websites that I ever ran into that wanted to use it.
> But then, there also weren't many (public) websites that I ever ran into that wanted to use it.
As I understand it there were weird pockets where organisations went hard in to activeX. IIRC it was used heavily by the South Korean government, and a lot of internal corporate intranet projects for all sorts of things.
That obviously caused massive problems a few years later when Microsoft tried to discontinue activex and make IE/Edge a normal web browser.
As someone who still has to support users of several ActiveX apps, turning off the "block unsigned ActiveX" setting goes with the territory of using it.
Everyone who runs Node runs untrusted code (depending on your definition of untrusted). No one I’ve ever worked with made an effort to review the source of the thousands of dependencies they were slinging around.
I’m pretty sure untrusted code means code you can’t trust, which includes any code that you haven’t either analyzed yourself or put through some sort of institutional review with auditable sign-offs.
It is how these conversations always go:
There’s a hole in the sandbox.
If you were trusting the sandbox, you were already doomed.
Nobody validates their code well enough to trust it. (we are here)
The ecosystem and industry is just irreparably damaged.
What am I supposed to do about that?
Non-solutions, because it is an impossible problem to actually fix
Web browsers rely on the sandbox. Almost everyone runs untrusted code single day. There are very few people who do not trust the sandbox.
It does not directly affect servers if one rejects your rather broad definition of untrusted, but does indirectly.
> I’m pretty sure untrusted code means code you can’t trust, which includes any code that you haven’t either analyzed yourself or put through some sort of institutional review with auditable sign-offs.
That is so broad that very people are running trusted code. You would need to ensure your entire stack down to the firmware it runs on had been analysed.
I would expect "untrusted code" to mean "code in a sandbox" or "code I'm not gonna run at all anytime soon", so running code from thousands of dependencies in node is effectively trusting all of that code, unless it is your direct expectation that it is malicious (and even then, aren't you trusting it to be malicious ?).
The trust we give to random dependencies like that is quite arguably unwarranted to a large degree, but it doesn't mean the code isn't trusted.
Serverless and CDN style edge compute are two scenarios that this may be relevant to, where untrusted or semi-trusted code may run in some construction on top of V8. Especially providers of those services are probably tuned in right now or ought to be.
I wonder how many bugs like this are found with and without fuzzing. I don't really know very much about this area but the diffs to fix these bugs are always a couple of lines and it's always very subtle. You'd basically have to have written the code yourself to know there's something wrong. Here's another example of what I'm talking about: https://zerodayengineering.com/insights/chrome-webrtc-cve-20...
That commit says it is for 1515930. The Chrome releases page says that CVE-2024-0519 is associated with 1517354, which is what I linked to. There may be a connection between CVE-2024-0519 and CVE-2024-0517, but none is mentioned on the Chrome releases page which is what I'm going by.
Windows 7 is not secure if it is connected to a network because it no longer gets security patches. Anyone running Windows 7 on a network connected computer does not care about security and will get hacked.
> Anyone running Windows 7 on a network connected computer does not care about security and will get hacked.
It's not so simple. If the Windows 7 computer is on a physical network with only trusted devices, and behind a firewall, and only running trusted programs, in most cases the only exposed attack surface is going to be the browser.
Age is irrelevant. Market share is. The first search result [1] places Windows 7 at 3.34% of Windows marketshare currently, which is significant, IMHO, but your market may vary from whatever this statistic tracks. 8.1 at 1.66% and XP at 0.64% could be significant, too, depending on your market. If you're going to support 7, you may as well support 8 and 8.1 too because it may not be any more work.
Can you yet get a laptop that fits XP all in cache?
Edit: It looks like you could probably pull it off with some trimming and a sufficiently expensive Epyc, but I think you'll have to wait a few years for laptops to manage. Hopefully by then you can take XP out back and but it once and for all.
It says severity high everywhere, but doesn't the attacker also need to break out of the sandbox to do actual damage? With this vulnerability alone you only gain remote code execution inside the sandbox.
In the demo video they're running Chrome using the --no-sandbox flag. Can this be exploited without that option? I can't actually test this myself at the moment, because the vulnerability only works on x86_64 machines.
Yes, it can be exploited, just inside the sandbox. I'm pretty sure this is why the write-up is always so careful to say "read/write inside the Chrome sandbox."
With the chain that's documented, you basically end up with full R/W/X control inside of the sandbox process, so what you can do is highly platform and version specific. For example, IIRC you used to be able to unmask Tor and many VPN and proxy users from inside of the sandbox using either JavaScript or native networking APIs. It's my recollection that this is less true on newer Windows versions, but I don't keep up with Chrome sandbox protection that well.
Presumably Exodus also have a sandbox escape that didn't get burned so they didn't include it in the writeup.
> Presumably Exodus also have a sandbox escape that didn't get burned so they didn't include it in the writeup.
I certainly hope not. I know these zero day exploits tend to be used almost exclusively against high profile politicians and journalists, but the threat still tempts me to just disable the JIT altogether (and maybe WASM too).
Oof, another reminder that it does not matter how aggressively you fuzz, it’s still fundamentally stochastic and you can miss things like this for years :-/
Well maybe such a JIT is an inappropriate choice for a sandbox. There are under-explored safe alternatives such as isomorphic interpreters e.g. https://blog.cloudflare.com/building-fast-interpreters-in-ru... personally I've written one such implementation that could hold it's own compared to a LLVM based JIT.
The whole point is the implementation and runtime for any safe language _requires_ code that is fundamentally unsafe.
If you write a safe interpreter your safety is still dependent on the compiler and runtime for your safe language having no errors.
This specific bug is in the implementation of a safe language, and the same can happen in any other (safe) language. People file bug reports on rustc, clang, llvm, etc all the time, and the only difference is that targeting them as an attack vector is not not particularly valuable as it's much harder to get a target to run your attack code, and the methods for doing so are much harder to hide. Note that these errors do not have to be any kind of safety error in the compiler for those languages, they can easily be erroneous codegen. These things happen.
As another example, I've seen use after free bugs in WebKit and JSC come up on HN over the years, and people blame C++ memory management, when the use after failure is incorrect management of the JS GC state in the GC runtime. If you have a GCd language, then code written in that language is definitionally incapable of making memory management errors, but if you are implementing the runtime that provides that safety you are inherently and unavoidably doing things that are "unsafe" under the definition of the hosted language.
The decision of many people is that JS needs to be fast, but if you disagree you can always see what the perf delta is. IIRC for non-hot code the JSC baseline JIT is maybe 10x faster than the interpreter (which is written in a pseudo assembly, so it's not taking any C/C++ overhead), and if the code is hot enough that it starts getting optimized that number just gets larger.
I'm not sure what language you were compiling where your interpreter was holding its own to LLVM, but the options that would make that plausible all imply the dominant component of the runtime was not the code being interpreted. e.g. along the same lines of people comparing python performance by benchmarking C and fortran math libraries.
Equating the provided memory safety of a Rust program without direct unsafe usage to a complex JIT built in C++ seems willfully ignorant. The attack surface would still be the mostly formally verified Rust type system and standard library https://plv.mpi-sws.org/rustbelt/.
For the JS lifetime machinery that's entirely out of rust's borrow checker shouldn't one verify the properties of unsafe code (which I imagine the garbage collector would use)?
As I understand it, Rusthornbelt exists to prove unsafe code at the cost of manual verification. As someone who's a novice in verification using model checkers, writing proofs for simple algorithms is hard enough already, so I don't see the viability of a fully verified JIT. Is there a CompCert-C equivalent for V8/JSC?
The isomorphic interpreter that I was talking about, and as shown in the cloudflare blog, does not generate new machine code. All it does is jump around in the statically verified safe Rust code. So it is extremely robust. Even if there are logic bugs in it, they will not manifest as UB.
My comment was more in the vein of every security bug that gets reported is followed with comments along the lines of "don't they fuzz their software", or languages like Zig that aren't memory safe but claim "debug allocators" and "support for fuzzing" obviate the need for memory safety.
A memory safe language does not need fuzzing to try and prevent memory safety errors from causing security vulnerabilities, as definitionally such errors are not exploitable. Obviously fuzzing is still valuable in such an environment because crashing at runtime is a bad user experience, but it's still superior to "trampling through memory with wanton freedom and continuing to do whatever attackers want".
That’s a dangerous line of thinking: memory safe languages can and do have memory safety bugs. There are many causes for this, from incorrect compilation (as seen here IIUC), bugs in the language runtime, concurrency problems, to unsafe language features. That doesn’t mean that there is no value in memory safe languages, they are a definite improvement. But, they are not the solution to all problems around memory safety. For example, even in Rust, which provides some of the strongest memory safely guarantees, there are memory safety issues discovered in the standard library.
Is your implication that the problem is that v8 is written in c++? I can’t find the details for the vulnerability and while it may be possible this is the problem the exploit could live in the JIT itself (that’s common for vulnerabilities within v8 itself since v8 has a very thin runtime). We don’t have any memory safe techniques for the output of JITs (or compilers by the way) - even if it were written in Rust or Java it’s possible the vast majority of security exploits in this space would still exist.
It's a horrifyingly complicated vulnerability that takes 28 printed pages to explain and one line of code to fix. I don't even want to know what kind of effort it took to discover this one.
The bug is not directly caused by V8 being written in C++. It's a miscompilation, and those can happen whatever language your JIT is written in.
But. But but but. It could be argued that the problem is indirectly related to it being written in C++. It's a tricky argument, but it might be worth trying. I will now try and make it. Please be aware though, that I am commercially biased, being that I work part time at Oracle Labs on the Graal team who make a JS engine (open source though!). It should hopefully be obvious that these words and thoughts are my own, not indicative of any kind of party line or anything. So, yeah, take it all with a solid dash of table salt.
One of the reasons a higher level language like Java or even Rust is more productive than C++ is the capacity for building higher level abstractions. Specifically, Java has very good reflection capabilities at both runtime and also (via annotation processors) compile time. High level and safe abstractions are one of the key tools used to make software more robust and secure.
If you wade through Exodus' explanation, the core of the bug is that whilst implementing an optimization in very complex code, someone forgot to update some state and this causes the generated IR to be incorrect. This sort of bug isn't surprising because V8 has several different compilers, and they are all working with complex graph-based IR in a low level and fairly manual way.
In the beginning the GraalJS engine worked the same way. JS was converted into bits of compiler IR by hand. It was laborious and slow, and unlike the Chrome team, the engine was being written by a little research team without much budget. So they looked for ways to raise the level of abstraction.
There are very few fast JS engines. There's V8, JavaScriptCore, whatever Mozilla's is called these days, and GraalJS. The latter is unique because it's not written in C++. It's not even just written in plain Java (if it was, this argument wouldn't work, because the vuln here isn't a memory corruption directly in V8's own code). GraalJS is written in something called the "truffle dsl" which is basically using Java syntax to describe how to create fast JIT compiling virtual machines. You don't directly implement the logic of a VM or compiler for your language in this DSL. Instead you express the language semantics by writing an interpreter for it in Java whilst also using annotations, a class library, a code generator that comes with the framework and a set of compiler intrinsics to define how your language works and also (crucially) how to make it fast through tricks like specialization. The code of the interpreter is then repeatedly fused with the data/code of the program being interpreted, partially evaluated and emitted as compiled machine code to execute.
This process doesn't guarantee the absence of miscompilations. Obviously, there's still a compiler involved (which is also written in Java and also uses some self-reflection tricks to be written in a high level way). But fundamentally, you aren't manually manipulating low level IR to implement a high level language. Nor are you writing several compilers. There's one compiler that's general enough to compile any language.
There is a bit of a performance sacrifice from doing things this way, in particular in terms of warmup time because partial evaluation isn't free.
But this does let you minimize the amount of code that's doing risky IR transformations! It's about as close as you can get to a "memory safe technique for the output of JIT". A JS engine built using this technique cannot corrupt memory in the JS specific code, because it's not emitting machine code or IR to begin with. That's all being derived from a reflection of the interpreter, which is itself already memory safe.
Also, obviously, working with complex graph structures in C++ is super risky anyway, that's why Chrome uses a garbage collected heap. V8 is super well fuzzed but if you don't have Chrome's budget, implementing a JIT in standard C++ would be quite dangerous, just from ordinary bugs in the parser or from UAFs in graph handling.
Like I said, this is kind of a tricky and perhaps weak argument, perhaps analogous to arguing about safe Rust (which still has unsafe sections), because there are still graph based optimizations in Graal, and they can still go wrong. But you can at least shrink those unsafe sections down by a lot.
That could be and that analysis really is quite long. I’ll have to take your word on that as I don’t have the experience you do. I do know that most JITs don’t have to even worry about this as they don’t need to worry about running untrusted code (not sure about the real world deployments for GraalJS). It’s also true that v8 has a lot more usage and vulnerabilities in it like this are a lot more valuable. So it can be hard to compare and contrast how different approaches impact vulnerabilities (+ comparing vulnerabilities is really difficult). But generally it is true that higher level abstractions can reduce certain classes of defects (not sure if this one falls into that but certainly others).
All that being said, the changes you suggest sound more like a design choice than something specific to a language. V8 has a complex build process and an object graph that should let you get the necessary compile time and runtime reflection capabilities.
Anyway, I think we can both agree that compiler research generally assumes trusted inputs but there’s not much research in building robust compilers and JITs that are secure against malicious input. We know generic techniques like fuzzing but no really robust designs (in terms of the level of protection we know related to memory safety)
Graal/Truffle languages can support sandboxing and GraalJS does. So it's designed to run untrusted code.
I think in this specific case it's really hard to say. It's sort of on the borderline. But we can imagine many other closely related cases where the higher level abstraction would help.
You could potentially do something like Truffle with C++ and LLVM, but I don't think it'd be easy. The grain of the language works against you. It's interesting if V8 already has added some of the infrastructure necessary.
You'd be surprised how much friction you'd have for C++ reflection. First, since it's a custom build step, you can do a mix of custom code gen and C++ constexpr/consteval for static reflection. Here's a header-only implementation for adding compile time reflection purely within the language [1]. And v8 already does dynamic code gen as part of its build process (to generate the snapshot to speedup instantiation of the isolate).
Some amount of dynamic reflection is also a must since JS is a dynamic language with reflection support + you need to walk the GC tree.
Of course none of this necessarily exists within the compiler part of the codebase as it's unlikely to be needed there, but clearly doable.
I don't know the specific details of reflection needed for the abstractions you reference and clearly V8 is still doing some amount of manual IR generation, so it's possible it would be a substantial investment to actually retrofit those techniques into v8 (+ the current capabilities may exist in the wrong part of the codebase for applying it to the JIT itself).
One would have to do a careful analysis of historical security exploits & specific techniques and their ability to prevent to figure out if it's worth adding those abstractions (especially since there is a potential performance tradeoff as you mention). As I said, I think there's insufficient research in this area to establish a compelling body of best practices (not to take away from the contributions of the GraalJS team to this space).
Chrome had many vulnerabilities that could be avoided with a safer language, but complex bugs in JIT are not one of them.
I think you could argue that the VM should be implemented in a less dangerous way that can be formally verified or better isolated, but that's not as simple as a rewrite in Rust.
Thank you for writing this. I am amazed that people are still surprised that systems have security bugs and get hacked. There are lots of security bugs in every major operating system, database, browser, framework, etc. These bugs are not there because the teams building these systems want them to have bugs. They are there because security is hard and no one knows how to build large systems with no security bugs.
Most hackers aren’t finding their own 0days like this. If a motivated state level attacker targets you, you’re in trouble.
But most companies that get hacked fail in much dumber ways - like failing to update chrome long after a bug like this has been fixed. Or using stupid, guessable passwords.
Of course we should have sympathy for the 1% of companies who fall victim to 0days from state level attackers. But I have no sympathy for the other 99% of data leaks where the devs forgot to put a password on a public mongodb instance, or let their login cookies be enumerable or something equally ridiculous. Just because we can’t make security perfect doesn’t mean we shouldn’t make it good.
James Mickens gave a lecture at a conference (I think it's this one: https://www.youtube.com/watch?v=tF24WHumvIc but I don't have time to actually listen through it) about how there are two different threat models for computer security: bored five year olds and the Mossad. And bored five year olds just try the same three things again and again, and as long as you take basic precautions you can protect yourself against them. You cannot protect yourself against the Mossad, don't even try.
When I first started paying attention to computer security I was at a start-up and tasked to rewrite their PCI infrastructure for credit card processing, so I did some research into the state of the art. That week news of a casino hack came out. Billionaire casino/media magnate and conservative donor Sheldon Adelson gave a speech in October 2013 about how the US should threaten to use nuclear weapons to destroy Iran's nuclear program. In February 2014 a 150 line VB virus was installed on his casino's network which wiped all of the hard drives it could find, costing the Sands hundreds of millions of dollars. This was at a casino, some place which absolutely cares about their computer security and presumably spends a lot on that security, and they failed to successfully protect themselves against a nation-state level threat.
So whatever the hell startup I was working at had no chance if someone at that level wanted it. We could stop the five year olds. Just not the nation-states.
None of these entities have unlimited resources or unlimited political cover. At some point you're making too big of a hole in the budget, too many people must be sacrificed and it's not worth it.
There's also the component of "there are millions of lines of existing C and C++ that continue to exist and the majority of new 'safe' languages are not designed to support gradual adoption/replacement". So you get gradual improvements to C++ that ostensibly make correct code easier (lets ignore string_view, etc) but no real path to actual safety without just rewriting everything all at once, which is an approach with a long and illustrious history of failure and major regressions even in "successful" attempts.
Is there a better way for something like an optimizing (jit) compiler? My barely informed understanding is that many of these bugs aren't soundness issues in the compilation process but instead the resulting executable code. I don't see how rust meaningfully helps with this problem.
Formal verification is often thrown around but my understanding is it can't scale to the complexity of something like an optimizing compiler.
It's relatively easy to find the offending commit by creating a unit test and using git bisect. I usually don't do it for public Chromium bug reports since it's extra work and $0 in extra rewards.
I wonder if any of these are avoided by disabling JIT, which I have done. And also, just how much of the codebase is JIT related? I also don't think C++ is always the problem. This is a complex language run-time, and there's all sorts of issues that can be language and language run-time related, regardless of it being written in Rust or C++, that manifest as out-of-bounds errors.
I couldn't find any information about work-arounds.
To take the point more seriously than you intended it: this is (apparently) a bug in a code generator. The C++ itself wasn't unsafe and didn't crash, it emitted binary code that did. A Rust/Python/whatever JIT could trivially have the same bug.
Commenters aren't suggesting Rust because it's not an area where implementation language is able to provide safety.
https://chromereleases.googleblog.com/2024/01/stable-channel...