If you look at the way code is written today vs. a few years back, one of the major changes is the transition to open source. What was once considered an unsafe methodology has grown and matured, and nowadays almost every software project uses open source libraries. Today, software engineers prefer to use existing open source code, instead of writing everything themselves.
The benefits are significant:
- Code development becomes even faster. It’s now more about welding existing pieces together, rather than building those pieces yourself. Today, open source libraries solve fundamental engineering problems, allowing engineers to focus their time on more complex tasks.
- Tools like package managers make it simple to manage and add 3rd party dependencies. Every programming language or IDE comes with an integrated package manager support.
- Overtime, the way APIs are exported and used becomes clearer and simpler. Open source maintainers offer clear APIs, simple documentation, and code samples.
- Its code, that they can scan for 0-day vulnerabilities
- Issues and security tickets, that are managed on GitHub, GitLab, etc. These issues can help find vulnerable areas for exploitation
- Current and past vulnerabilities, that can be very helpful when the library in use is not up to date. Those vulnerabilities have detailed descriptions, advisories, and even the patches themselves are open source. An attacker can utilize those vulnerabilities and attempt to attack the application, and if the library uses an old version, the attack will succeed.
Prioritizing Vulnerabilities
Tracking existing vulnerabilities is important, but it’s not enough. The average project has dependencies, that in turn have their own dependencies. Overall, there can be hundreds or thousands of libraries with hundreds of vulnerabilities in your project. Nowadays, solving those vulnerabilities can take lots of time, while developers need to put efforts into developing new features as well. Managing security vulnerabilities of 3rd party packages is often not a one-time thing, but rather an on-going process, so it’s important for an SCA tool to prioritize the risks. This way, developers know what the most crucial risks to solve are. But how do you prioritize a vulnerability? The popular method is to prioritize vulnerabilities by the CVSS—a score given to a vulnerability based on the impact, how easy it is to exploit, etc. Every vulnerability that was made public has this score. However, this methodology is too simplistic, since exploitability is the most crucial aspect.Exploitability of a Vulnerability
Let’s assume that a vulnerability is triggered by a foo() method in a library that you’re using. If your code doesn’t call foo() in any flow, either directly or indirectly, the vulnerability is in fact not exploitable. If so, the priority of fixing it is low and efforts should be redirected to exploitable vulnerabilities instead. Looking at it from an attacker’s perspective, for a vulnerability to be exploitable:- The method foo() needs to be called. This can require a carefully crafted input, whose processing will trigger a call for foo().
- The attacker needs to control the data flow for foo(). Usually, calling a method with “regular input” won’t trigger any unwanted behavior. The unwanted behavior is triggered when a carefully crafted input from the attacker reaches foo(). Meaning, the vulnerable method needs to be callable and its input controlled.
- Current prioritizations of vulnerabilities are defocusing. Instead of fixing exploitable vulnerabilities first, efforts are put into risks that may be sometimes irrelevant.
- They may be considered as False Positives. You would assume that a critical risk is a top priority, but if the relevant code flow can’t be reached, there’s nothing critical here.
- The true number of vulnerabilities that need to be addressed is in fact much lower than assumed today, and that’s good news for developers. Fewer vulnerabilities mean far less effort to remediate them.












