Re: Levels of blame...
What about:
The system that was designed so that updating one module of a piece of software, reliably, on multiple versions of - say, picking an OS entirely at random, Windows - is non-existent or almost impossible.
If people could just say "Is this module, a Java module called X, installed, or could you install that for me, please OS, along with its dependencies?" programmatically and have it reliably work cross-platform, that would be some way to a solution.
Then you can end the static binaries, hard-coding and compiled-in-libraries and literally just say "This software needs OpenSSL, please install it" and then updates to OpenSSL take place for EVERY piece of software that needs to use it.
But we don't have anything like that, from a programmatic point of view. Even Linux distros, that's an action outside the scope of programming and into the scope of package creation and OS integration. There is no programming language that I'm aware of that automatically sorts out such things for you so that when you #include popular_library it makes sure that popular_library exists, or asks the user if they want to install it, and keeps it up to date. The onus is all on the packager, not the developer (and they are rarely the same person), and on the individual package management for that particular OS (there's no cross-platform way to do this).
Perl CPAN.
PHP libraries.
Java dependencies.
DLL's.
You name it, the problem rears its head in every language in common use, and the languages always consider it "outside the scope" of their remit to provide for it.
If you want to stop building statically building in old versions, and thus propagating vulnerabilities in un-updateable code, you have to design an OS and a language that takes account of things like this. There's no way we should be manually creating dependency files, packing up RPMs with funny little tags, or running setup programs that have to be told to run off and download MSVCRT from the MS website and then installing it and then switching back to the "setup" program if it worked.
Java is no different here. But Java was always a highly-specced langauge with the capability for this kind of thing. Aren't java packages almost exclusively referred to by a corruption of their origin domain name? (com.java.sun, etc.). There was scope there to make it automatic, tie it in with DNS, XML requests, etc. and it wasn't done.
The closest we get is things like Javascript libraries and XML DOM's where you can instruct a browser to run off and download the latest JQuery or use a particular version of the Google web fonts or whatever, and it tries its best to do so. And that works quite well, to be honest. Millions of website rely on it.
But still you see websites that copy/paste their code to local URLs and things like that. And yet no "offline" programming language or mainstream operating system has facilities for this kind of thing.
Nobody who wrote a piece of code 10 years ago is going to bother to keep the libraries up to date. They probably no longer work on it, no longer have the power to do anything about it, no longer paid to do that, no longer remember or care. But we still just assume that software will live forever in the same state once its written.
Imagine if, when OpenSSL was flawed, or MD5 was cracked, we could just mark it as obsolete, mark an upgrade path, and EVERY piece of software that dealt with them worlwide was updated to use a replacement library or object class as soon as it was next executed?