You could argue Go is safe from memory vulnerabilities, and that'll be 99% correct (we can't know what will happen if some very strong organization (e.g. a nation-state actor) will heavily invest in exploiting some Go program), but it still isn't memory safe, as per the definition in Wikipedia:
> Memory safety is the state of being protected from various software bugs and security vulnerabilities when dealing with memory access, such as buffer overflows and dangling pointers.
Honestly, forget about Go: when was the last time you heard of a modern application backend being exploited through memory corruption, in any language? I know that Google and Meta and the like use a good amount of C++ on the server, as do many smaller companies. That C++ code may skew ‘modern’ and safer, but you could say the same about newly-developed client-side C++ code that’s constantly getting exploited. So where are the server-side attacks? Part of the answer is probably that they exist, but I don’t know about them because they haven’t been disclosed. Unlike client-side attacks, server-side attacks usually target a single entity who has little incentive to publish deep dives into how they were attacked. That especially applies to larger companies, which tend to use more C++. But we do sometimes see those deep dives written anyway, and the vulnerabilities described usually aren’t memory safety related. So I think there is also a gap in actual exploitation. Which probably has a number of causes, but I’d guess they include attackers (1) usually not having ready access to binaries, (2) not having an equivalent to the browser as a powerful launching point for exploits, and (3) not having access to as much memory-unsafe code as on the client side.
This is relevant to Go because of course Go is usually used on the server side. There is some use of Go on the client side, but I can’t think offhand of a single example of it being used in the type of consumer OS or client-side application that typically gets attacked.
Meanwhile, Go is of course much safer than C++. To make exploitation possible in Go, not only do you need a race condition (which are rarely targeted by exploits in any language), you also need a very specific code pattern. I’m not sure exactly how specific. I know how a stereotypical example of an interface pointer/viable mismatch works. But are there other options? I hear that maps are also thread-unsafe in general? I’d need to dig into the implementation to see how likely that is to be exploitable.
Regardless, the potential exists. If memory safety is a “threshold test” as you say, then Go is not memory-safe.
I agree though that the point would best be proven with a PoC of exploiting a real Go program. As someone with experience writing exploits, I think I could probably locate a vulnerability and create an exploit, if I had a few months to work on it. But for now I have employment and my free time is taken up by other things.
It happens all the time, but it’s a bit hard to find because “modern application backend[s]” are usually written in Go or Python or Rust. Even so, you’ll find plenty of exploits based on getting a C or C++ library on the backend to parse a malformed file.
Yes, this is an enormous effort to construct exploits, but constructing exploits for C/C++ code is much much easier and gives not less, or even more, benefit. Therefore it makes sense the efforts are focused on that.
If/when most C/C++ code in the world will be gone, I assume we'll see more exploits of Go code.
Can you show me any reasonable proof of concept (without using unsafe etc.) in Go that leads to similar memory corruption and is exploitable for RCE?