> The funny thing is that most languages that people use that criticize 'C' are usually at the core levels written in C.
The difference is that the people using these higher level languages only depend on a single set of maintainers who need to get the primitives right once instead of every random coder needing to manage buffers, garbage collecting unused memory, threading, and a host of other landmines on each and every project.
Funnily enough the proliferation of those scripting languages has made it easier to get a picture of what's going on if you do get rooted by the consequences of running a flakey C app. In the old days the md5 binary would be broken and you were pretty much screwed if the other guy was good. But these days you can hammer out manual md5 algorithms and do other stuff using perl, python, and anything else at your disposal - things that are deployed by default on contemporary unix distributions. Better still, if you've got a book on unix systems calls you can absolutely fly through troubleshooting techniques that weren't practical before. (Sure the bad guys could just delete your VMs, but then that is a clear sign that the system has had it - and that signal is useful in and of itself - one of the difficult things in a situation like that is making a call on how far gone your system is so you can set short-term priorities in the lead up to rebuilding everything)
Good thing those coders wading around what you seem to consider the shallow end of the coding pool are not writing things like our nameservers, web servers, operating systems, or anything else important. Oh, that's right, they are. And they keep fucking up. Repeatedly.
When this keeps happening over and over again it is time to consider the possibility that the problem isn't the craftsman but the tool.
The advantage of using lots and lots of glue languages is that it forces the important bits to be loosely coupled, adds flexibility to the development and deployment process, and leads to systems that are easier to comprehend and reason about. The only things that should be opaque binaries are system libraries and VMs/runtimes. Everything else should be "glue".
Given the number of lines of C code out there the number of fuckups is a lot less than you'd expect. Because C is usually used in gatekeeper situations (operating systems, compilers, servers, network stacks) when there is a breach it is serious.
I find it hard to conceive of a posix compliant OS written in a higher level language, especially because of the lack of deterministic behaviour when handling interrupts and allocating memory. C is mind numbingly simple at that level which is exactly why it is used in these situations.
But every language makes it possible to write insecure code, C has its own unique challenges:
It isn't that long ago that somebody managed to get an exploitable scenario out of UTF-8, it took me a long time looking at the code to see how it was even possible. In a higher level language that sort of thing is more difficult to achieve, that's for sure.
The difference is that the people using these higher level languages only depend on a single set of maintainers who need to get the primitives right once instead of every random coder needing to manage buffers, garbage collecting unused memory, threading, and a host of other landmines on each and every project.