Does Code Reuse Endanger Secure Software Development? (threatpost.com)
msm1267 quotes ThreatPost: The amount of insecure software tied to reused third-party libraries and lingering in applications long after patches have been deployed is staggering. It's a habitual problem perpetuated by developers failing to vet third-party code for vulnerabilities, and some repositories taking a hands-off approach with the code they host. This scenario allows attackers to target one overlooked component flaw used in millions of applications instead of focusing on a single application security vulnerability.
The real-world consequences have been demonstrated in the past few years with the Heartbleed vulnerability in OpenSSL, Shellshock in GNU Bash, and a deserialization vulnerability exploited in a recent high-profile attack against the San Francisco Municipal Transportation Agency. These are three instances where developers reuse libraries and frameworks that contain unpatched flaws in production applications... According to security experts, the problem is two-fold. On one hand, developers use reliable code that at a later date is found to have a vulnerability. Second, insecure code is used by a developer who doesn't exercise due diligence on the software libraries used in their project.
That seems like a one-sided take, so I'm curious what Slashdot readers think. Does code reuse endanger secure software development?
The real-world consequences have been demonstrated in the past few years with the Heartbleed vulnerability in OpenSSL, Shellshock in GNU Bash, and a deserialization vulnerability exploited in a recent high-profile attack against the San Francisco Municipal Transportation Agency. These are three instances where developers reuse libraries and frameworks that contain unpatched flaws in production applications... According to security experts, the problem is two-fold. On one hand, developers use reliable code that at a later date is found to have a vulnerability. Second, insecure code is used by a developer who doesn't exercise due diligence on the software libraries used in their project.
That seems like a one-sided take, so I'm curious what Slashdot readers think. Does code reuse endanger secure software development?
If you use a third-party library that has a bug in it, you'll be exposed to the same bugs that everybody else using that library are. On the other hand, if you go at it alone, your implementation will have bugs of its own. And if the library is well-maintained, it'll have fewer bugs than the thing you make from scratch.
Implementing the common functionality from scratch can easily become another kind of "not exercising due diligence", particularly when dealing with complex code. Or to put it another way: code reuse may endanger secure software development, but not reusing code may also endanger secure software development.
Most people just install software like they would a washing machine, once it's in, they don't touch it anymore except to run it, after all, a washing machine has a strong motor, some controls, valves and a belt, there is virtually no maintenance necessary and if it ever does, it's cheap enough and long-lasting enough you can just throw it out and replace it.
Maintenance is a necessary part of anything that is a very complex machine and is not protected. A car is a good example, it sits outside so it needs to be protected against burglary but also against the elements, salt and accidents as well as regular maintenance to replace worn and outdated parts.
Computer systems are as complex and vulnerable as cars, they sit 'outside' on the Internet, where they have to be protected against 'bad people' and just regular outdatedness but often they are considered as dumb appliances (if not actually called that by a vendor).
People need to pay more attention and fund their "computer-mechanics", not just the manufacturers of their "car" and demand that they are able to inspect and repair their own stuff regardless of who invented it.
Custom electronics and digital signage for your business: www.evcircuits.com
The alternative, which is everyone writing their own mostly terrible implementations, is far worse.
Granted, if it's closed-source you have to trust the library vendor. If it's open-source, you either have to do due dilligence or trust someone else who claims to have done so.
I assume we are talking about re-using source code, linking with staticly-linked libraries, and using and "private copies" of shared libraries binaries (e.g. /usr/local/bin/applicationname/lib/lib1.so or C:\Program Files\Application\DLLs\MyDll.dll). With "public" shared binaries (/usr/lib/sharedlib.so or C:\Windows\...\MSDLL.DLL), you are relying on the library or OS vendor to keep things patched.
Here's an example:
I know of a popular product that uses its own private copy of Java. If the vendor doesn't update their customer's versions of Java on a regular basis, an attacker can exploit it, even if the user is updating the "Oracle" version of Java on a regular basis. That's bad. On the other hand, they would probably be in a worse of a position of the vendor re-wrote the functionality of Java in-house, as that code would have its own set of bugs and it would likely NOT be as maintined as Java is. The solution is to use the "Oracle" version of Java instead of a private copy, OR push out updates to the private copy within a day or two of Oracle pushing out their updates.
Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
What's needed is better operating system management, not better development practices.
Once a piece of software is patched, the problem is fixed. That's not the issue at hand. The issue is that that fix then does not make it back to production systems in a decent time.
What's needed - and I've posited this a number of times for a number of things - is a central repository which lists which, say, linux packages are secure and which are not. Which algorithms, hashes and cryptosystems are compromised or not.
Then there needs to be an API - running a production system live on the Internet? It will check its version numbers and package hashes against the centralised "uncompromised" versions service. If there's a discrepancy -a package that's been marked as potentially compromisable, but which has an updated or patched version available - the OS is tainted much like the kernel is tainted. If MD5 is retired and any software on the machine still utilises it, the system is marked as tainted as soon as it checks into the centralised API.
We've needed this for hashs and crypto systems for a long time. SHA-1 is retired, but how do you KNOW that? And how do you know what uses that? Nobody would recommend building a system using WEP or MD5 in this day and age but nowhere is that listed in a queryable manner.
And then you start saying "Why weren't Facebook checking their systems against the Secure Software Database? Their own fault if they were compromised.", "Why did Yahoo not re-hash with a listed-good algorithm as soon as their existing hash was obsolete?", "Why were they compromised? Because they turned off database checks and updates? Idiots".
There needs to be a way for production systems to algorithmically say "This is no longer acceptable practice" and start making a fuss such that the system maintainers are forced to start upgrading, with specified timescales (the API could easily obsolete stuff on a set timescale, with warning enough to test changes to newer algorithms).
Then, if you're compromised because you ignored this, or because you hard-coded MD5 instead of using libraries, all the fault will be in the your third-party, unlisted libraries. And then you might be able to actually start forcing vendors to publicly state "All our software uses the latest database-compatible algorithms, software and patches" rather than just hope that someone at Google isn't just running Slackware 2.0.
The software can be fixed in a trice. The problem is getting that fix out to production systems in good time, and not being able to sufficiently shame those who don't manage their systems (it's easy to blame a hack on the software, rather than your lax update practices).
Don't you think some code that has been run 10 times might be more secure than code that has been run 10 million times? After all it's less worn out.
Code reuse is a fundamental tenant of secure software development lifecycles. You reduce the chance that you introduce new vulnerabillities by limiting the amount of new code per project to the core business logic and leveraging existing modules for the support infrastructure.
That said, if the module you reuse has problems then you aren't necessarily better off. The modules need to be vetted and maintained appropriately. Code reuse isn't the problem so much as taking random crap from the internet that solves your problem without assessing its suitability for inclusion given your threat model or properly assessing it for vulnerabilities.
Monoculture can be an issue from certain perspectives -- flaws in the libssl portion of OpenSSL affect a huge percentage of the internet. However, they only need to be fixed once and consumers of the library can all receive the update, assuming proper patch management in the environment. If your company uses 15 different libraries to perform a specific software function across different product lines without a basis in engineering requirements constraints, you're doing it wrong.
Security being a subset of correctness, I think overall it is b.s. to say code reuse is a problem. You just need to make sure you are reusing correct, vetted and maintained code. I.e., don't take strange code from someone's github to use in your enterprise software without reviewing it.
Because Java! Not the worst programming language ever, but the problems that come from garbage collection and programmers who THINK they understand it.
We need to get off of the HTML/CSS/ crazy drunken bandwagon and get back to basics! Re-boot and re-tool the the entire process because if we don't we are just screwed and more break ins will happen as the things become more and more complex. You need to let DBA's build the database portions of things and secure access. You need to let Systems people write HARDENED code. Let web guys make things pretty. You need to stop demanding a a single point tool and go back to individual inter working parts, written by competent coders, which are then put through a very severe hardening process.
Hey KID! Yeah you, get the fuck off my lawn!
A well known, maintained library such as OpenSSL? You're far more secure using the open source library. Not only do you need to be an expert to correctly and securely implement that level of cryptography, but it can contain all sort of subtle bugs you're unlikely to catch.
Now if you're talking about some random library you found on github because some guy on stackoverflow said to use it? That makes you less secure. Don't put random things you found on the internet into your program without reading the code, understanding what it does, and doing a full audit on it first.
And there's a special place in hell for anyone who uses gradle, nvm, or anything else that automatically downloads the library for them without specifying an exact version. You're just asking to be screwed by a trojan horse. Leftpad was about the best case scenario, imagine if leftpad had changed their code to be a backdoor instead?
I still have more fans than freaks. WTF is wrong with you people?
So does reinventing the wheel. So does cut-and-paste coding.
Code reuse leads to insecure software in much the same way that breathing leads to cancer.
Post may contain irony: discontinue use if experiencing mood swings, nausea or elevated blood pressure.
(Edit: the one arguably major vice of code reuse is that it makes lazy over-inclusion easy and tempting. We had a story a few days back about some fairly common 'default' desktop linux setups that were vulnerable because of a bug in the implementation of the emulator of one of the chips in the SNES. Outside of chiptunes enthusiasts and some of the more serious console emulation wonks, almost nobody is likely to ever see SPC audio; and the few people who will are likely to know what it is and be minimally inconvenienced by having to open their package manager and install libgme. But, since it was available as a Gstreamer plugin; the more the merrier! and into the default config it went. Given that software not produced under very, very, unusual attention to detail and correctness, which is almost all software, can be reasonably expected to risk some bugs; you don't want to be throwing in libraries that you have little or no use for, just because it's easy, which is certainly less likely if everything you include you have to write yourself; but aside from that there just isn't a(realistic) better option to code reuse. If your practices are too shoddy to even keep your 3rd party dependencies up to date; your DIY attempt is unlikely to be pretty; while if you are good enough to DIY properly; you certainly aren't obligated to stop; but you can probably handle keeping an eye on 3rd party dependencies.)
You're like one of those people who thinks Java was written with more Java and its just Java all the way down, aren't you?
I understand your logic. You're not being stupid, but you are misinformed.
> hacking scripts will become useless since every system will have different vulnerabilities
The fact is, over 90% of the CVEs are the SAME 12 or so vulnerabilities - hard-coded default passwords, SQL injection, etc. I can and do write scripts that find "new" vulnerabilities in software we've never seen before. One-off, custom software, especially web applications will pretty reliably have one or more of a gew specific vulnerabilities. You may have heard of the "OWASP Top 10"; most one-off software contains at least two or three of those ten.
Once I (or the script) detects anything else about the software, we can know more specifically which vulnerabilities it has, before we even test it. For example, I've seen a dozen different scripts named "download.php" or similar. All but one suffered from the exact same three vulnerabilities.
Reuse has to be done *right*. Most of the people with religious fervour about code reuse do not necessarily do it right. Doing it right means you must review the code and know what it does, know if it fits into your design, know how to fix it when it breaks (and it will), and so forth. Cutting and pasting is dangerous. For a larger piece of code you want long term support that is stable without a constantly changing API, but do not expect to actually get support unless you're a giant company. I see so many who waste so much time wheedling to get support when they could just fix it themselves in a tenth the time. To some people "code reuse" is a synonym for "never code", and they love it because it often turns out they don't know how to program anyway.
How about avoid C common mistakes instead of avoid C would be a better statement. C done right is a solid language to use depending on the project.
I suppose you know how timing side channel attacks are done? All those layers of abstraction make it possible to accurately predict and alter code path length? Oh, and they do automatically handle things like proper memory scrubbing of keys when no-longer valid? Right?
These things need low level hardware access to manage, and are hard even then where there is less in the way screwing with it. It is nearly impossible to handle properly on highly abstracted languages running in managed virtual environments like Java and C#.
Yes those abstractions help avoid specific classes of vulnerabilities, but can open a whole host of just as bad context specific ones when talking about security stuff like encryption. This is why we should only let specialists in that specific field do such implementations and have them vet each others code.
Yup. Everyone wants a philosophical fix for the security (and general QA) problem. Nobody wants to admit the need for many hours of less-than-prestigious, methodical work.
Someone had to do it.