Identifying Vulnerable Dependencies In .NET Projects
May 07, 2024· #.NET #NuGet #DevOpsSec #GitLab CISome time ago, I was working in a company that was building a SaaS that was written in .NET. The code base was a decade old, and like many companies using Microsoft technologies, it had been through a few framework upgrades. The intent was to move to modern technologies and refactor outdated components, but the execution was rather poor. By the time I put on my engineering manager's hat, many of the NuGet packages in the solution were out of date and even deprecated.
In Python and Go projects, I rely heavily on linting, static analysis, and formatting tools. Not having these essentials would make me and my teams less productive. So the first thing I did was understand what modern .NET brings to the table in this area. And I started by scanning the NuGet packages we use in all of our projects in a single solution for potential vulnerabilities.
It turned out that developers could simply run dotnet list package --vulnerable
locally
to keep an eye on security. But without automation, it's too easy to forget about that.
My first local scan produced the following result:
...
Project `X.Infrastructure.Calendar` has the following vulnerable packages
[net6.0]:
Top-level Package Requested Resolved Severity Advisory URL
> System.Data.SqlClient 4.8.3 4.8.3 Moderate https://github.com/advisories/GHSA-8g2p-5pqh-5jmc
High https://github.com/advisories/GHSA-98g6-xh36-x2p7
The given project `X.Infrastructure.Common` has no vulnerable packages given the current sources.
Project `X.Infrastructure.Currency` has the following vulnerable packages
[net6.0]:
Top-level Package Requested Resolved Severity Advisory URL
> System.Data.SqlClient 4.8.3 4.8.3 Moderate https://github.com/advisories/GHSA-8g2p-5pqh-5jmc
High https://github.com/advisories/GHSA-98g6-xh36-x2p7
Project `X.Infrastructure.Locker` has the following vulnerable packages
[net6.0]:
Top-level Package Requested Resolved Severity Advisory URL
> System.Data.SqlClient 4.8.3 4.8.3 Moderate https://github.com/advisories/GHSA-8g2p-5pqh-5jmc
High https://github.com/advisories/GHSA-98g6-xh36-x2p7
The given project `X.Infrastructure.Locker.Tests.Unit` has no vulnerable packages given the current sources.
The given project `X.Infrastructure.Pool` has no vulnerable packages given the current sources.
Project `X.Infrastructure.Repositories` has the following vulnerable packages
[net6.0]:
Top-level Package Requested Resolved Severity Advisory URL
> System.Data.SqlClient 4.8.3 4.8.3 Moderate https://github.com/advisories/GHSA-8g2p-5pqh-5jmc
High https://github.com/advisories/GHSA-98g6-xh36-x2p7
The given project `X.Infrastructure.Rules` has no vulnerable packages given the current sources.
...
As you can see, there are several projects vulnerable to CVE-2022-41064.
.NET Framework System.Data.SqlClient versions prior to 4.8.5 and Microsoft.Data.SqlClient versions prior to 1.1.4 and 2.0.0 prior to 2.1.2 is vulnerable to Information Disclosure Vulnerability.
To get rid of the issue, it's enough to upgrade the package:
dotnet add package System.Data.SqlClient -v 4.8.6
Now, how can developers prevent such situations? You already know the answer: automation!
After sharing my observations with the team, I created a merge request with a new GitLab pipeline that runs for every open merge request and master branch.
These are the changes in the .gitlab-ci.yml
manifest:
stages:
- security
vulnarable-dependencies:
stage: security
image: mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim
before_script:
- dotnet restore
script:
- dotnet list package --vulnerable 2>&1 | tee vulnerable-packages.log
- >-
! grep -qiw "critical\|high\|moderate\|low" vulnerable-packages.log;
if [ $? -ne 0 ]; then
echo "🚨 Found vulnarable packages";
exit 1
else
exit 0
fi
artifacts:
when: always
expire_in: 12h
paths:
- vulnerable-packages.log
only:
- master
- merge_requests
tags:
- docker
The pipeline will fail if any of the projects in the solution have vulnerable packages. The downloadable log file contains the list of vulnerabilities and their severity.
This way, the team is always aware of the state of the dependencies and can take action to fix them.
References: