DEV Community

Andrey Krisanov
Andrey Krisanov

Posted on • Originally published at akrisanov.com on

Identifying Vulnerable Dependencies In .NET Projects

Some 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.
...

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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:

Top comments (0)