Published on
This post was written by Chris Romeo during his tenure at Security Journey.
Unlike wine and cheese, software does not get better with age—in fact, its security strength decreases over time. This is because of software obsolescence.
The problem is more significant than any other software security issue because it includes all the other liabilities. Take the OWASP Top 10 as an example. The list contains the most prevalent application security risks, and one (A9) is “using components with known vulnerabilities.”
And those components can introduce every other risk on the OWASP Top 10, including injection (A1), broken authentication (A2), and sensitive data exposure (A3).
Could a piece of third-party software be so old that it no longer attracts the attention of attackers? This occurred with Heartbleed, for some products. They were not vulnerable to Heartbleed because they were running a version of OpenSSL so old that it did not have the heartbeat code included.
But antique libraries are a double-edged sword, because what other vulnerabilities lay within an early version of the software?
This is a third-party software world, with software consisting of libraries that are strung together into a solution. The software supply chain is the journey your application goes through—it includes all the components you rely upon to build your solution.
The 2019 State of the Software Supply Chain report by Sonatype exposes the depth of the problem. The report noted that each day, on average, there are 21,448 new open-source releases, with the average enterprise downloading 313,000 open-source components per year.
The depth of the software obsolescence problem comes into focus with Java and JavaScript. One in 10 Java component downloads have known vulnerabilities at the time of download. JavaScript weighs in with a whopping 51% of components that have weaknesses.
The downloading of known vulnerable components represents a severe challenge to the security of any application. It is difficult enough to detect a component vulnerability after you have deployed. If you start with a known vulnerable component during development, you are setting yourself up for an imminent software security failure. It’s not a matter of if, but when.
Another report, on the state of open-source security by Snyk, is a continuation on the definition of the same problem. It found that 37% of open-source developers skip security testing, and the median time from when a vulnerability is found to when it’s fixed is two years.
Most popular Docker images contain, on average, 30 vulnerable system libraries. Software obsolescence is not going away. Here’s are top tools and approaches for embracing it.
Culture comes first: It’s a journey
Security culture dictates the emphasis given to security and is just as crucial for an open-source development project as it is for the team building out your application.
From the open-source dev team perspective, as an industry, we must improve the general security knowledge of those writing the components. We must reach the point where 100% of developers feel responsible for the security of the elements they create.
But impacting the open-source dev team is only a small portion of the solution. Many open-source groups do fix their vulnerabilities in a timely fashion, but those libraries are still downloaded and used by your development teams.
From your development team’s perspective, you must build a culture where each developer embraces software obsolescence and is continuously on the lookout. We must reach an era in which developers believe that even though they did not write the code, any vulnerabilities introduced are a reflection of their application and craftsmanship.
Exercise your codebase
A secure development lifecycle must address software obsolescence and provide an organization-wide mandate and expectation for the update of the software. A stance of “the build will break if we have vulnerable components included within” is an approach that must exist to prevent software obsolescence.
In a DevOps world, where software releases can occur hundreds of times per day, there is an advantage in that there is a daily exercise of a codebase. Tools can detect known vulnerable components and break the build until resolution.
For those shops that are still trudging along at a slower pace, you need a process to exercise your codebase on a weekly cadence at a minimum to determine if any vulnerable components exist.
Break your builds the right way
Both commercial and open-source technology exists that you can use to scan codebases and detect whether any known vulnerable software components exist within it. Source code repositories are gaining features that hunt for vulnerable parts in your code as it sits in the repository, and open-source tools are focusing in on this problem.
Here are a few examples of tools and solutions for various languages and environments:
- Dependency-Check is a software composition analysis utility that identifies project dependencies and checks if there are any known, publicly disclosed vulnerabilities. Currently, the tool supports Java and .NET; additional experimental support exists for Ruby, Node.js, and Python, and there’s limited support for C/C++ build systems (autoconf and cmake).
- OWASP’s Dependency-Track provides an enterprise-scale solution and uses Dependency-Check as a source of input. Dependency-Track is an intelligent software supply chain component analysis platform that allows organizations to identify and reduce risk from the use of third-party and open-source components. Dependency-Track monitors component usage across all versions of every application in its portfolio to proactively identify risk across an organization.
- GitHub provides an integrated service called security alerts for vulnerable dependencies. When GitHub discovers or receives notification of a new vulnerability, it identifies public repositories (and private repositories that have opted into vulnerability detection) that use the affected version of the dependency. Then it sends a security alert to repository maintainers and generates an automated security fix.
- Bundler-audit is a patch-level verification for the Ruby language. It checks the bundler package management system for vulnerable versions of gems in Gemfile.lock and for insecure gem sources.
- NPM audit scans a Node.js project for vulnerabilities and automatically installs any compatible updates for vulnerable dependencies. When you execute npm audit, it submits a description of the dependencies configured in your package to your default registry, and asks for a report of known vulnerabilities.
The process with all of these various tool options is to install them and ensure that they break the build whenever they detect a vulnerable component. Force developers through your standard process to update sensitive parts.
The OWASP Component Analysis page lists other commercial and open-source tools.
Craftsmanship needed here
The problem of software obsolescence is not going away, so change the culture, deploy the tools, and embed those tools into your process. Break the build when you detect a problem component. While the software build that breaks may be your own, that break may prevent the next significant front-page data breach.
While no problem is ever easy, with hard work you can eradicate vulnerable parts. A focus on craftsmanship and the right set of tools will prepare your teams for success.