Software dependencies: How to manage dependencies at scale
What are software dependencies?
A software dependency is a code library or package that is reused in a new piece of software. For example, a machine learning project might call a Python library to build models.
The benefit of software dependencies is that they allow developers to more quickly deliver software by building on previous work. Software dependencies have revolutionized application development over the past few decades, but they also introduce risks that are frequently overlooked.
What are the types of dependencies?
Software dependencies come in two types:
Direct: Libraries or packages your code calls directly.
Transitive: Libraries or packages your dependencies call. These are dependencies of dependencies.
Both types of dependencies require careful management to control the risks involved. Transitive or indirect dependencies require extra consideration because it’s not immediately obvious that they’re being used in an application. Dependencies become nested inside other dependencies, forming a complex dependency tree, which makes it easy to miss when your application uses a library with vulnerabilities.
Snyk Report
State of Open Source Security 2022
A look at software supply chain complexity and risk in collaboration with The Linux Foundation.
Why managing dependencies is mandatory
In the early days of software dependencies, downloading and installing a required library was tedious work. This made it impractical to reuse smaller packages. Over the last two decades, however, dependency managers like Node Package Manager (NPM) for Node.js and Maven for Java have made it feasible to work with smaller packages, even those consisting of a few lines of code. The number of packages available for developers has since exploded, and software dependencies are now a key ingredient of modern applications.
By using pre-built software dependencies, developers can deliver software faster and on shorter release cycles. Yet dependencies introduce risks that are often overlooked. Including external software as a dependency means you’re relying on its developers to correctly write, test, and maintain that code.
On top of the security vulnerabilities that may be present in those program dependencies, they can also become outdated, limiting the quality of the software that calls them — or even causing it to fail. These dependencies could have bugs or security issues that impact the performance and risk profile of the application. Finally, there may be licenses involved which have potential legal or liability ramifications.
Framed in this way, managing dependencies to minimize the risks associated with them is critical. Yet many organizations devote little attention to dependency management. When software is running properly, they see no need to fix what’s not broken. On top of this, dependency management is hard. Transitive dependencies can have multiple links, or even circular dependencies. Updating one dependency can potentially break the entire chain, leaving you in dependency hell.
Why you should manage open source dependencies
The earliest iteration of software dependencies saw companies purchasing code packages from known and reputable vendors. Now, the majority of dependencies are open source third-party libraries, which adds a factor of complexity to dependency management. The open source contributors who write and maintain the code used in production software are likely to be external to your organisation.
When open source libraries first emerged, developers often copied and pasted lines directly. This made it impossible to track and upgrade components. More modern techniques involve using a package manager to manage open source components, or wrapping open source libraries in in-house modules. These more modern approaches make it easier to use open source code in applications. Despite this explosion in open source components, developers often have little understanding of the vulnerabilities they can introduce.
Due at least in part to the massive explosion in the amount of code being created, security experts are constantly uncovering vulnerabilities in open source components. If a malicious party discovers one of these vulnerabilities, they can use it to launch attacks (Equifax breach), especially in very popular packages (Log4Shell). Furthermore, open source licenses stipulate usage terms and violating them can lead to hefty fines and reputational damage.
For these reasons, it’s essential to develop a system for managing open source dependencies throughout their lifecycle. This includes developing and enforcing policies around how developers handle open source components.
5 Dependency management challenges
As we've seen, open source dependencies allow developers to deliver applications more quickly, but they also expose organizations to security and legal risks. Managing these dependencies requires care, particularly transitive dependencies since they can result in nested layers of dependencies. One approach to managing and mitigating risks around open source dependencies is software composition analysis.
Software composition analysis (SCA) is an application security testing approach for tracking and analyzing software components. SCA includes both application security methodologies and tools that monitor software to track the components used as dependencies. SCA is not limited to open source components, but the growth of open source dependencies have led to a proliferation of SCA tools in recent years.
To successfully manage the risks around open source dependencies, SCA tools need to overcome a few key challenges:
Transitive dependencies can obscure open source packages under several layers of visibility, making it difficult to gain full visibility into every open source package an application calls. Snyk research has found that the vast majority of vulnerabilities lie in these obscured dependencies, so developers may not even be aware they’re using open source packages with security vulnerabilities.
It's important to understand how each ecosystem handles dependencies. Factors such as lock files and package resolution during installation affect how vulnerabilities are identified. SCA tools need to account for these nuances to accurately identify vulnerabilities that are relevant. For example, this could help detect and prevent dependency confusion attacks, a method which was successfully used to access and exfiltrate data from Yelp, Tesla, Apple, Microsoft, and others.
The amount of vulnerabilities discovered within software dependencies can number in the thousands. It's critical for SCA tools to have a system for prioritizing efforts to identify and resolve vulnerabilities.
SCA tools need a reliable source that identifies vulnerabilities in time to secure them.
SCA tools need to move quickly enough to keep pace with developers. If they fail to do this, developers may end up ignoring or bypassing security checks.
How Snyk’s dependency management tool mitigates risk
Traditional security approaches focus on the end of the development process, as opposed to integrating it into DevOps workflows. Snyk Open Source positions developers as key players in their organization’s security position by integrating out-of-box into existing workflows and tools. Security and operations manage and oversee the process, while developers use Snyk tools to continually secure development pipelines from within CI/CD tools. Fixing security issues at the development stage before code is anywhere near production is by far the safest and cheapest option
Snyk covers all aspects of application security. It provides a Dependency Tree View to identify dependencies and vulnerabilities in them, and automatically updates dependencies as they evolve (read how this works in Java and Python). Snyk automates scanning within the IDE, so that developers can find issues, prioritize them, implement fixes, and merge the updates during development. Alerts automatically issue when vulnerable functions are called at runtime. Integrations with SCMs including GitHub and GitLab help to roll the tool out across new and existing code projects, and enable automated fix PR’s to be generated reducing the impact on valuable development time
This developer-first security approach enables developers to find and remediate bugs in code and dependencies in real-time. Vulnerabilities are caught earlier, which lessens their impact on the development lifecycle. A comprehensive vulnerability database gives hand-curated vulnerability descriptions. All items in the database are analyzed and tested for accuracy, and a CVSS score and vector are assigned to each vulnerability. Vulnerability descriptions give insights into exploitability, licensing, security history, and maintenance for flagged libraries.
Pearson, the world's largest education company, started using Snyk’s automated dependency scanning to minimize their risk exposure. Once developers were able to use the platform, the DevSecOps team wanted to make sure they knew how to resolve issues quickly as well.
Snyk’s automated remediation feature prioritizes vulnerabilities to minimize the actions developers need to take to fix them. This helps reduce the risk exposure Pearson faces from outdated dependencies, newly discovered security vulnerabilities, and licensing issues.
“It can be a bit daunting when teams log into Snyk and see hundreds of vulnerabilities,”…“so we encourage teams to look at the remediations rather than the individual issues. You can have 20-30 vulnerabilities which are fixed with just one dependency upgrade. This is easier for teams to action.”
Scan your dependencies for vulnerabilities
Automatically find, prioritize and fix vulnerabilities for free with Snyk.
How to secure your software dependencies
Software dependencies play a key role in modern software development. They enable developers to reuse code others have written, allowing for faster delivery and shorter cycle times. As a result, their use has exploded, but they introduce risks and vulnerabilities that organizations often underestimate.
Open source dependencies are a particular area of concern. The majority of dependencies modern developers use are open source, which means production software relies on external contributors to write, update, and maintain these dependencies.
Comprehensive monitoring of dependencies is therefore critical, but it’s hard to monitor every dependency an application uses — particularly transitive dependencies.
Snyk Open Source is a SCA tool that automatically detects and monitors dependencies throughout the development lifecycle. Unlike other solutions, Snyk takes a developer-first approach and enlists developers as active participants in application security.
To learn more about dependencies and their ramifications for application security, read our report, The State of Open Source Security.
Thanks for reading and stay secure.