Managing vulnerabilities in open source dependencies
In September 2024, I had the opportunity to present at the Secure Open Source Software (SOSS) Community Day in Vienna, hosted by the Open Source Security Foundation (OSSF). My talk, titled “Managing Vulnerabilities in Open Source Dependencies,” covered important aspects of securing third-party dependencies.
This blog post aims to share the talk content in a written format.
Keep reading to learn why vulnerabilities in third-party dependencies are a significant security concern and what practical steps you can take to address them. Specifically, we’ll walk through the entire process — from selecting a software composition analysis (SCA) tool and rolling it out to effectively triaging findings — along with some additional tips to help along the way.
Why third-party dependencies vulnerabilities matter
Before addressing vulnerabilities in third-party dependencies, it’s essential to understand the risks they bring to your software and the importance of having a process in place to manage them.
Any software project typically consists of both in-house and third-party code. In enterprise software, third-party code can make up about 50% of the total codebase while in smaller projects that percentage is often significantly higher.
The more code you have, the more potential attack surface you introduce. Although this is true for in-house code as well, there’s a key difference between in-house code and third-party code: control. Or maybe…the lack of control.
With in-house code, you have full control over the development process. You can ensure that it passes through peer reviews, security reviews, and security testing. This process can be tailored to meet the security standards you set.
In contrast, with third-party code, you lack that control. Your choice is limited to whether to use it or not — you can’t influence how that code is written, reviewed, or tested.
Additionally, supply chain attacks — where vulnerabilities in third-party code are leveraged to attack systems — are becoming increasingly prevalent. One notable example is the critical vulnerability discovered in 2021 in Apache Log4j, a widely used logging library for Java. While this particular vulnerability wasn’t widely exploited, it had the potential to cause devastating damage if left unpatched, allowing attackers to execute arbitrary code and compromise entire systems.
The importance of software composition analysis (SCA) tools & how to evaluate them
Now that we’ve covered why addressing vulnerabilities in third-party dependencies matters, let’s explore how to tackle them effectively.
The first step in addressing these vulnerabilities is simply being aware that they exist. Unfortunately, given the sheer number of dependencies we rely on — along with the transitive dependencies they bring — identifying vulnerabilities manually is highly impractical.
This is where software composition analysis (SCA) tools come into play. SCA tools automate the identification of vulnerable dependencies, making it much more feasible to stay on top of potential risks.
There are many SCA tools out there, both open source and commercial. When selecting a SCA tool, a common mistake is looking for the most popular ones and then deciding which one suits our needs best. This is somewhat the opposite of the ideal process, as it creates bias.
Instead, before evaluating any tools, it’s important to first define and document your SCA requirements. For each requirement, specify whether it is a “must-have” or a “nice-to-have.” This approach will make the evaluation process much smoother, as you’ll have established what is absolutely necessary and what is not
To help you get started with defining your requirements, we’ve provided an SCA requirements template here. It closely mirrors the requirements we used internally when evaluating SCA tools.
Once you’ve solidified your internal requirements, begin researching SCA tools. By reviewing their documentation, you’ll be able to determine which tools meet most of your needs. From there, select a maximum of three tools for further evaluation, keeping time and effort in mind.
The next step in the evaluation process is testing the tools in your environment. Pay close attention to their accuracy (ensuring no false positives or negatives) and completeness (verifying that all relevant issues are detected). Many evaluations focus heavily on administrative settings and integration capabilities but miss the most critical aspect: validating that the SCA engine is reliable and trustworthy.
Rolling out your SCA tool
With our tool evaluation complete, it’s time to begin the rollout!
One option for rolling out the SCA tool is to integrate it with all repositories at once and then start triaging the reported issues. However, this approach comes with a significant challenge: You’ll likely be overwhelmed by the number of findings, making it difficult to prioritize effectively. Questions like “Which repository should we triage first?” or “Which severity levels should take priority before triaging the next repository?” can quickly become chaotic.
To avoid this, a more structured approach is a phased rollout.
Start by identifying your most critical repositories. Limit this list to a maximum of five so that the initial rollout remains manageable. Rank these repositories by business impact — consider which ones would have the most severe consequences for your users or customers if a vulnerability in a third-party dependency was exploited.
Begin by integrating the first repository with the SCA tool. Set a fixed interval for integrating each subsequent repository — 15 days, for example.
Once the first repository is integrated, dedicate the next 15 days to triaging all high and critical findings from the SCA tool’s report. After 15 days, integrate the second repository and repeat the process, working on its high and critical findings. Continue this phased approach with the remaining repositories.
In summary:
- t=0: Integrate Repo 1
- t+15 days: Mitigate all high and critical findings in Repo 1; integrate Repo 2
- t+30 days: Mitigate all high and critical findings in Repo 2; integrate Repo 3
- … and so on.
Key highlight: Once a repository is integrated with the SCA tool, ensure that new pull requests introducing dependencies are scanned.
This is crucial because after a repository is integrated, you want to prevent new dependencies with vulnerabilities from entering the codebase. If they do appear, it should be a deliberate decision by your security team. This allows you to focus on addressing historical vulnerabilities without worrying about new ones being introduced.
As for medium and low-severity vulnerabilities, these can be tackled using a similar phased approach once all repositories have been integrated.
Triaging findings
Well done! You’re rolling out your SCA tool in your repositories and are now ready to start triaging the findings. So, how do you approach triaging each one?
The key is to conduct a timeboxed investigation for each finding, focusing on two main questions:
- Is it a test dependency?
- Is the vulnerable dependency — or the vulnerable function within it — actually reachable in your software? In other words, is it exploitable?
The first question is usually straightforward to answer, but the second one can be trickier. This is why a timeboxed investigation is crucial — it ensures you don’t spend excessive time on each finding while still gathering enough information to assess the risk.
It’s also important to weigh the time spent investigating versus updating the dependency. If updating the vulnerable dependency is faster than conducting an investigation, it’s generally best to go ahead and update it.
Another effective strategy for triaging findings is to establish a regular maintenance schedule for updating dependencies. This can be particularly useful for addressing low-severity vulnerabilities that might otherwise get deprioritized. A consistent update cycle ensures that you’re not only addressing vulnerabilities reactively but also keeping your dependencies up to date proactively.
Final thoughts
Managing vulnerabilities in third-party dependencies requires thoughtful planning, the right tools, and a structured approach. Choose your SCA tool carefully, and roll it out with a clear plan for addressing historical vulnerabilities.
Mitigating vulnerabilities in third-party dependencies involves collaboration across the organization; it’s not just the responsibility of a single team. Both the security team and engineering teams need to work together, which is why securing buy-in and commitment from engineering leadership is essential for long-term success.
To learn more about security at Mattermost, visit the Mattermost Trust Center.