Understanding & Managing NuGet Package Vulnerabilities
by Eric Seng, on Oct 13, 2021 2:35:42 AM
If you have any experience with NuGet packages, you know that you don't need to stress about every vulnerability in every package your team is using. Even "critical" vulnerabilities are often practically impossible to exploit.
But you still need to know about them. Does this vulnerability impact our code? Should we upgrade the package? Should we work-around the vulnerability? And so on.
In this article, I'll explain how NuGet's built-in vulnerability scanning works, how it compares to the CVE/NVD, and how to deal with all these vulnerabilities without having to manually scan every package.
NuGet's Built-in Vulnerability Scanning
Vulnerabilities are simply reports of possible security threats, and they come in different shapes, sizes, and severity.
To help discover these vulnerabilities, the NuGet client has a built-in vulnerability scanner that connects to the GitHub Advisory Database. You can also see package vulnerabilities on nuget.org.
However, as I'll explain later, this is a very basic vulnerability scan - and is no replacement for an automated vulnerability scan tool that looks beyond GitHub's database.
Using the NuGet CLI to scan for vulnerabilities
It's pretty easy, just enter the command dotnet list package –vulnerable on each project to get a list of vulnerabilities, and then decide project-by-project what to do based on the vulnerabilities found.
The scan will connect to the GitHub Advisory Database and display any current vulnerabilities within your top-level packages. You will be able to understand the version resolved, the severity of the advisory, and a link to the advisory for you to view.
To see transitive package vulnerabilities, use --include-transitive.
Finding vulnerabilities on NuGet.org
NuGet.org will also show you what packages have vulnerabilities, and details the severity and how it can be resolved.
Note: The example packages listed above have since been patched or have been marked deprecated and unlisted.
GitHub Advisories vs CVE vs NVD
NuGet's built-in scan only uses the GitHub Advisory Database, which has under 200 total NuGet vulnerabilities as of today. However, there's a much larger, and more comprehensive vulnerability database out there called Common Vulnerabilities and Exposures (CVE).
The CVE system goes far beyond open-source projects hosted on GitHub, and is essentially the centralized list of all publicly known vulnerabilities and exposures. It's a massive list.
Each vulnerability in the CVE system contains:
- CVE identification number
- Description of the vulnerability
- Severity score from 0 - 10
- ... along with many other details
Anyone can report a vulnerability and request that it be added to the database. After a quick review (not an analysis - more on that later), the vulnerability can then be seen by anyone.
GitHub Advisories are also CVE
Where things can get a bit confusing is how GitHub Advisories and the CVE are related.
GitHub is one of many CVE Numbering Authorities (CNA), which means it can create CVEs directly, without human review. This means that all GitHub Advisories are CVEs, but not all CVEs are GitHub Advisories.
There are a lot of other CNA, including Adobe, Microsoft, and Cisco, which means all vulnerabilities they discover in their products will end up in the CVE as well.
National Vulnerability Database (NVD)
The CVE is essentially a centralized database, with vulnerability reports from users and vendors. They haven't necessarily been analyzed by a third-party.
This is where the US Government's National Vulnerability Database (NVD) comes in. The NVD performs an analysis on CVEs by aggregating data points from the description, references supplied, and any supplemental data that can be found publicly at the time.
These findings are then published along with all of the other information in the CVE.
Ultimately, this means the best source for vulnerabilities is the NVD.
NuGet's built-in scanner is very limited
Because NuGet only uses the GitHub Advisory database, it only has access to a subset of all reported vulnerabilities. However, even if NuGet were to expand these built-in capabilities to use the NVD, there's still a bigger issue
What about vulnerabilities that have been reported after you run the command?
Newly Reported Vulnerabilities
New vulnerabilities are discovered in old software all the time. For example, CVE-2021-22876 describes a recently-reported vulnerability in curl that's been around since August 2020.
On the same token, the exact NuGet package version that passed a vulnerability scan a month ago could have a new severe vulnerability reported next month.
The only way to address these newly-reported vulnerabilities is to routinely scan packages that you are currently using. This means you need to scan the packages used by current production applications to see if there are newly published vulnerabilities. And of course, this is in addition to scanning new builds of new applications.
That's a lot of scanning. We're talking every package used by every project that's currently being developed or has already been deployed.
Obviously, this is not something you can do manually, with NuGet's built-in scanning.
Scripting your own Routine Scanner?
In theory, you could write a script that uses NuGet's built-in scanner against all of your projects - both the deployed and in-development releases. This script could then aggregate all of the results, and prepare some kind of report.
And then what? This report of 100+ vulnerabilities would still need a human to review and make decisions based on the report. That means it would need to become someone’s job -- or part of everyone’s job -- to scan and make decisions on vulnerabilities.
Does this vulnerability impact our code? Should we upgrade the package? Should we work-around the vulnerability? And so on.
Every time you run this report, that person will need to make the same decision, each and every time. All in all, it's a lot of work to scan for a vulnerability that, in all likelihood, is practically impossible to exploit.
So, what can you do about it?
Use ProGet to Scan for Vulnerabilities
ProGet's Vulnerability Scanning feature can, in part, automate both your scanning and assessment of NuGet packages. Vulnerabilities that you deem too severe will prevent those packages from being downloaded from ProGet.
There are two benefits to using this over NuGet's built-in vulnerability scanning.
- When you run automated vulnerability scans through ProGet, your decisions to block or allow specific vulnerabilities are essentially remembered. They're then applied the next time they are found in a scan.
- Unlike NuGet's built-in vulnerability scanning, ProGet's vulnerability scans connect to the National Vulnerability Database, which means you'll see a lot more vulnerabilities in your packages.
In addition, ProGet can be configured to auto-assess vulnerabilities within a certain severity score. So you can set a rule that automatically blocks all packages with critical (8.0+) severity or set a rule that allows all packages with low (0-2.0) severity.
⚠Vulnerability Scanning Is Not a Cure-All
NuGet vulnerability scanning doesn't do anything more than connect to the public GHSA database. It's an important step in your security process but improperly relying on it will make things less secure.
It's easy for teams to fall into a false sense of security, believing packages without reported GHSA vulnerabilities are fine to use. Worse still, it gives teams the false impression that since the package is fine today, it’ll be fine tomorrow.
Automating your vulnerability scans with ProGet and introducing a routine human-reviewed process for all your packages is the best way to ensure your NuGet packages meet your every-changing security requirements. Regularly assessing your vetting process will also set your organization up for success as code often changes, even day to day or hour to hour.