News and Notes from the Makers of Nexus | Sonatype Blog

Dependency management: Versions choice and the software supply chain

Written by Luke Mcbride | January 17, 2023

Writing original software "from the ground-up" is often touted among developers as a great feat, requiring skill and intellect. But creating brand new software or re-starting the process with existing software comes with many caveats.

Instead, most developers are focused on building software more efficiently through the use of third-party software components to solve common problems such as activity logs and secure connections. These dependencies are taken from freely available open source repositories and have become a crucial part of the development process.

This connected system of software development what's often referred to as the software supply chain.

Software components don't stand still

Using software developed externally means relying upon a project that is actively changing and improving. This ongoing effort is known as "dependency management," and keeping these components from gathering dust is an ongoing task.

Because outdated software can carry vulnerabilities that might be exploited by a bad actor, good dependency management means keeping your software up-to-date. Just like in manufacturing, not having optimum parts can negatively affect the quality of the end product. And software development is no different.

Today, this fact is complicated by sheer scale: not only does most software developed today include third-party, open source components, it’s now in the majority. It's estimated that 85% of modern software is built from component parts. Total dependencies are also increasing with the average Java application containing 148 dependencies, up from 128 last year.

However, there's another wrinkle when optimizing dependency management: it's frequently better to update to a version that's merely close to the most recent release.

When the latest isn't the greatest

When a development team updates their software dependencies, selecting the absolute latest version isn't ideal, even excluding experimental "beta" or "release candidate" versions.

Example of a “release candidate” download for the popular spring-shell project.

One of the most famous examples of avoiding the newest version was the "Heartbleed" vulnerability in 2014. Here, the issue was within a widely-used security library OpenSSL exposed millions of users' secure connections. However, programs that had not updated to the latest version (v1.0.1) were not vulnerable. As a result, projects that were slow to update either deliberately or by accident, didn't risk exposure of customer data.

Another more recent example was seen in 2020 with the SolarWinds attack, where the latest version was compromised.

What version is best is rarely straightforward and there are often multiple options to choose from. The average Java project, for example, releases 10x per year. Which one do you choose?

Choosing good versions

In our efforts to understand how teams optimize software development, Sonatype looked at how organizations typically handle out-of-date and vulnerable software dependencies. Unfortunately, we're seeing overall update practices, with only 25% of components actively updated with commercial engineering teams.

Teams taking pains to update their software are in a far better position. However, when engineering teams focus on updating dependencies, there are two frequent but less than ideal routes: 

  • Using the latest version – As noted by the Heartbleed and Solarwinds example above, this is not always wise.  Our current data is based on the Sonatype Safety Score, which applies the best rating to the most recent release only 3% of the time. In fact, the optimum version is, on average, 2.7 versions behind.

  • Using the most popular version – This is possible by looking at the total download statistics for a given dependency. Although many developers assume the majority will choose wisely, this too is unreliable.

There are a variety of ways to choose the ideal version from a project you rely upon, and the selection process is complex.  Last year's report saw the right one described as "living close to the edge" selected less than a third of the time (31%). We have since updated our analysis to point to an even smaller "optimal" group (pictured below).

The various dependency management strategies, zooming in on the “Living Close to the Edge” option and its “Optimal” sub-group.

Help manage open source

The number of components, available versions, and criterion for choosing the best version is already a burden and getting heavier.  The best option for many teams will be to introduce some dependency management tooling.

Automated tools can also reduce the total number of required component upgrades over time, saving time, developer frustration, and money. Combined with better version update timing (only update when you need to), we estimated benefits for a medium-sized enterprise. These organizations could save 14 days per development team annually with optimal upgrade decisions.

Available time and cost savings for optimum version management.

Implementing a better update practice will not only improve code quality but can accelerate your mean time to repair if a defect is discovered.

The best results come from the best parts

Today's software is built using an expansive set of open source projects, and organizations can empower teams to choose wisely. Taking time to find and use better parts in your software can lower risk and improve efficiency.

You can read more about this and other topics in our 8th Annual State of the Software Supply Chain report.

Related