OWASP - Secure your dotnet app by scanning for vulnerable nuget dependencies in CI pipelines
OWASP
1 Articles
In this article, let's learn about scanning for Vulnerable Nuget Dependency
and break the build to avoid
malicious code in dotnet.
Table of Contents
Introduction
Understanding and mitigating vulnerabilities in software dependencies is crucial in modern development. While leveraging
open-source
libraries enhances productivity, it also introduces
potential risks
that necessitate robust defenses
. Nuget packages are
the popular way to consume external libraries in .NET applications. However, these packages can contain
vulnerabilities
that can be exploited by attackers.
This can be manually checked by developers, but it is not a scalable solution
. It is also not feasible to
keep track of all the dependencies and their versions. Starting .NET 8, there is a support for auditing packages
.
But as of writing this, NuGet Audit
is available starting from NuGet 6.8, the .NET 8 SDK (8.0.100)
.
I'll also teach you alternate approach if you are not in .NET 8. In this article, we will learn how to scan for vulnerable Nuget dependencies and break the
build in CI pipelines.
Nuget Audit
The restore
command automatically runs when you do a common package operation such as
loading a project for the first time
, adding a new package
,
updating a package version
, or removing a package
from your project.
A description of your dependencies is checked against a report of known vulnerabilities
on the
GitHub Advisory Database.
To enable the audit during restore, you need to add the following MSBuild
properties in your
.csproj
file.
<NugetAudit>
<NugetAuditLevel>
<NugetAuditMode>
There are different values available for above properties as shown below.
MSBuild Property | Default | Available Values | Description |
---|---|---|---|
NugetAudit |
true |
true and false |
If you wish to not receive security audit reports, you can opt-out of the experience entirely by setting the value to false |
NuGetAuditLevel |
low |
low , moderate , high and critical |
If you'd like to see moderate , high , and critical advisories, set the value to moderate |
NuGetAuditMode |
direct |
direct and all |
If you'd like to audit both top-level and transitive dependencies, you can set the value to all . NuGetAuditMode is not applicable for packages.config projects |
Here is what all .csproj
file looks like with the above properties in I Love DotNet.
Code Sample - Nuget Audit to check for vulnerable nuget package and fail build for critical vulnerability
Excluding Vulnerabilities
First of all, I will not recommend excluding vulnerabilities. But if you have a valid reason to exclude vulnerabilities, you can do so by
adding <NoWarn>
to suppress NU1901-NU1904
warnings or use the
<NuGetAuditLevel>
functionality in your .csproj
to ensure your audit
reports are useful to your workflow.
Warning Code | Reason |
---|---|
NU1900 |
Error communicating with package source, while getting vulnerability information. |
NU1901 |
Package with low severity detected |
NU1902 |
Package with moderate severity detected |
NU1903 |
Package with high severity detected |
NU1904 |
Package with critical severity detected |
Scanning in CI Pipeline
If your projects are targeting .NET version less than 8, then you can read this else you can skip this section.
You can now list any known vulnerabilities in your dependencies within your projects & solutions with the dotnet list package --vulnerable
command. You will see any 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.
If you are interested in seeing vulnerabilities within your transitive packages, you can use the --include-transitive
parameter to see those.
We can add --format json
parameter to get the output in json format. The
specification
of the json can be found here. This can be used to parse the output and take necessary actions. So all we need to do is to run this command in our CI
pipeline and fail the build if there are any vulnerabilities.
Code Sample - UNIX command to check for vulnerable nuget package and fail build
The above code dumps the JSON
output to list.json
file and
recursively
checks for severity
key under projects and returns
non-zero exit code
if there are any severity KV pairs. If there are no severity keys then just print the
messgae and continue the build.
Thats it. This should work as expected. But this will fail even if a Low
severity vulnerability is found.
You can adjust this solution to fail your workflow for some specific severity level e.g. Critical
or
High
by updating jq filter i.e. select(test("Critical|High"))
.
This is how it is done in the ilovedotnet
CI pipeline.
Code Sample - UNIX command to check for vulnerable nuget package and fail build for selected severity
Summary
In this article, we have learned about the new tools
that NuGet
provides to
help you scan
your NuGet packages for security vulnerabilities
.
These tools should help you secure
your software supply chain and take action today. We also leveraged this tool
and added functionality to break the build
if any vulnerability is found. This is a great way to ensure that your
software is secure and that you are not introducing any new vulnerabilities into your software. If you're interested in the best practices that you can
check out the Microsoft documentation
on best practices for a secure software supply chain.