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.
https://www.zdnet.com/article/microsoft-70-percent-of-all-se...
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.