I mean, the threat model is that
1. Memory leaks/errors are bad
2. Programmers make those mistakes all the time
3. Using memory safe languages is cheap
Therefore,
4. We should use memory safe languages more often
The problem with memory unsafe languages isn't that they can crash. It's that they won't crash. And instead allow an attacker to load up malicious code into the application.
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.
Memory safety is valuable! I wouldn't want to implement anything in a memory-unsafe language if I could avoid it, and, thanks to Rust, I can virtually always avoid it now. There's ways to make bugs easier to chain and exploit, and memory unsafety is a big one.
But, while I know nothing is a panacea, memory safety is especially not a panacea. We have over a decade worth of experience with software built principally in memory-safe languages; it's hard to find a modern web application --- increasingly, it's even hard to find a modern mobile application --- built in a language as bad as C. And, as you know, all these memory-safe applications are riddled with vulnerabilities. They don't have memory corruption vulnerabilities, but I'm still game-over'ing app pentests, and very unhappy with myself when I can't.
Billions and billions of dollars. Large organizations like Microsoft and Google have published numbers on the proportion of vulns in their software that are caused by memory errors. As you can imagine, a lot of effort is spent within these institutions to try to mitigate this risk (world class fuzzing, static analysis, and pentesting) yet vulns continue to persist.
Rust is not the solution. Memory-safe languages are. It is just that there aren't many such languages that can compete with C++ when it comes to speed (Rust and Swift are the big ones) so Rust gets mentioned a lot to preempt the "but I gotta go fast" concerns.
1. Memory safety issues are the cause of a very large number of security vulnerabilities (often most of them for projects written in C or C++, depending on the software).
2. Memory safety-related issues have a relatively high probability of being turned into remote code execution, which is one of the most if not the most severe outcomes.
3. C and C++ projects have been empirically observed to have orders of magnitude more memory safety problems than projects written in other languages do.
4. The additional classes of security vulnerabilities that managed languages tend to foster do not have the combined prevalence and severity of memory safety problems.
So, we would be better served in security by moving to memory-safe languages.
> "Memory unsafe languages" is maybe one percent of one percent of the problem.
Multiple distinct large scale software projects have found that 60-70% of severe CVEs are due to memory safety violations[1]. The White House has called for projects to use memory safe languages [2]. The Android Project has seen an incredibly substantial drop in security vulnerabilities concurrent with their rapid shift to using memory safe languages in New code, with the correlation being so tight and the number of vulnerabilities having been so constant before that they are forced to conclude that memory safe languages have helped[3]. So your claim that memory unsafe languages are maybe 1% of 1% of the problem is not only completely unsubstantiated, but almost certainly false given all of the available information.
And your jab presumably at Rust for being a "fad" similarly holds no water. It is the only language that has actually offered a practical means of eliminating memory safety violations at compile time, statically, without needing a runtime or garbage collector or to give up zero cost abstractions, meaning that is the only relatively memory safe language with a solid shot at working in the fields where C and C++ were ordinarily used. That really doesn't seem like a fad to me. Or stupid.
> In conclusion, the empirical research supports the proposition that using memory-safe programming languages for these projects would result in a game-changing reduction in total number of vulnerabilities.
I think this is too strong a conclusion. How many of the major data leaks and ransomware attacks exploit memory safety issues? Not many. The bulk of them target misconfigurations, vulnerabilities caused by bad text-based protocols, logic errors in software, and social engineering.
That's not to say memory safety doesn't matter, and you can get very pernicious and subtle bugs when you get too clever in C-based languages. That said, the languages that boast about their memory safety are written in C/C++ (python, ruby, Java, llvm) and run on operating systems that provide process isolation with memory safety written in C/C++ on top of hypervisors which are also written in C/C++.
You can argue, as the article does, that use of C/C++ inevitably results in many memory safety issues, and that therefore we should use memory safe languages. Except this doesn't take into account the entire categories of vulnerabilities that have been entirely eliminated because of good C/C++ abstractions like process isolation, virtual memory, filesystems, tcp-ip, hypervisors, and so on. But we take these luxuries for granted, and the benefits they confer become invisible.
I think there is a much more mundane lesson here. Good abstractions prevent entire classes of vulnerabilities, and bad abstractions are leaky no matter how careful you are. C and C++ are pretty bad languages insofar they give you limited options for building good abstractions, but with careful programming it can be done and much of the best and most reliable and most complex software is written these low level memory unsafe languages and all major security advancements we've actually made in the real world are still implemented in memory unsafe languages.
Memory safety is certainly a problem. But so is the ability to execute data. I'm scared by the use of any language that has that capability for security-critical applications.
Agreed. But memory safety is really such low-hanging fruit right now. Given that memory bugs still produce massive quantities of severe vulnerabilities, it seems appropriate to hammer on that aspect of languages.
If memory safety ever becomes a practically solved problem (e.g. somebody's running an OpenBSD-style count of how many days since a new memory bug popped up and it gets past, I don't know, hate to be greedy, how about 3?), then I'll be merrily banging away on the other aspects.
And if the language has a direct impact on the efficiency and safety of the product, then what?
A memory-safe language dramatically reduces the frequency of memory safety bugs, which are the foremost cause of security vulnerabilities in software like browsers. This is an inconvenient conclusion that everyone wants to deny, because it's, well, inconvenient. But that doesn't make it less true.
> Memory safe languages make it harder to create a specific types of vulnerabilities and can even keep them in check when they occur which is real a tangible benefit, but those same assumptions and errors will just produce different vulnerabilities.
No, because:
1. Not all such errors become vulnerabilities. An array index out of bounds exception triggered by a page causes an annoying crash in a memory safe language. In a non-memory-safe language, it is an out of bounds write that can be used to set up fun things like ROP chains.
2. Errors such as use after free simply don't exist in memory safe languages. There is no logic error that typically causes UAF: it's just straightforward failure to perform bookkeeping that a compiler and/or runtime does for you in most languages.
3. Not all vulnerabilities have the same severity. Memory safety problems tend to cause the worst of the worst: remote code execution.
Your comment seems to ignore all the evidence that shows approx, 70% of security related issues come from those memory unsafe languages. Two independent large companies found that same statistic on two entirely different and large code bases. Google and Microsoft.
You can ignore those findings as you like, but that is why so many people are interested in Rust.
Highlighting a different systemic problem is not at all an argument against avoiding this problem. Indeed, if memory safety were the only problem to worry about, then I'd be less worried about it, because we could spend more time on it. But it isn't, there are all sorts of other things to worry about, simultaneously.
> This would be like judging SQL statements as fundamentally unsafe because websites written in PHP tended to (specially in the early 2000) be written in a very unsafe manner where user input was put directly into SQL strings.
This is indeed a good example, but supports my argument rather than yours. If we had devised ways to make it impossible (or incredibly hard and weird) to introduce sql injection vulnerabilities at the language level, then that would be excellent. One less thing to worry about!
I don't have a unique grudge against memory safety issues. It's just one type of issue that we've spent a lot of time devising solutions to that don't just boil down to "be very careful" and I'm generally supportive of any solution to any problem like that, if the tradeoffs are acceptable.
But I agree with you that it's a great thing to have language and library support that make memory safety issues significantly less common and problematic (to be clear, I only just heard of Odin from this article, but I think it looks pretty awesome on initial glance), and that that gets to the level of solution that we have for sql injection in practice. I think there are somewhat better alternative solutions available in the case of memory safety, but they have different tradeoffs.
> What remains is a matter of what attracts you to programming: are you interested in having explicit control over a system to make it do what you want, or are you more interested in expressing some abstract ideas in an abstract mathematical virtual machine?
I'm mostly interested in the first thing, but I think these are both false choices. There is a language that provides that explicit control with more memory safety (rust) with a different trade off (language complexity), and most other languages are memory safe without being focused on expressing abstract ideas in an abstract mathematical virtual machine (go, java, python, etc. etc.).
I think it's a bit funny that in an industry that (supposedly) prides itself on "meritocracy", there are many people that refuse to use (or learn) performant memory-safe languages, when memory-safe code is always better than memory-unsafe code (in terms of resource usage, reduction of bugs, etc, etc.).
reply