Safeguard
Application Security

.NET and NuGet dependency vulnerability management

NuGet packages have delivered RATs, crypto stealers, and undisclosed data collection to .NET teams. Here's how to detect and defend against .NET/NuGet supply chain risk.

Priya Mehta
DevSecOps Engineer
7 min read

In March 2023, JFrog researchers found 13 malicious NuGet packages — including one named "Coinbase.Core" — that had racked up more than 166,000 downloads before removal, each dropping a PowerShell-based crypto stealer on install. Five months later, ReversingLabs tracked a separate campaign that used more than 700 packages abusing NuGet's MSBuild .targets integration to run code silently during a build, not just at install time. By July 2024, the same actors had pivoted to IL weaving, hiding a SeroXen RAT loader inside otherwise legitimate compiled binaries across 60 packages and 290 versions. None of this required a zero-day. It required developers trusting dotnet add package the way they trust apt install. .NET and NuGet security is now a distinct discipline, not a subset of generic dependency scanning, and teams that treat it that way are the ones catching these campaigns before a build server executes them.

Why is NuGet a growing target for supply chain attacks?

NuGet is a growing target because it executes code earlier and more quietly than most package ecosystems — at restore and build time, not just at runtime. A malicious install.ps1 script or a custom .targets file bundled inside a .nuspec package runs the moment dotnet restore or msbuild touches it, often inside a CI pipeline with far more privilege than a developer's laptop. ReversingLabs documented this exact pattern in August 2023: attackers packaged malicious MSBuild targets inside more than 700 counterfeit NuGet packages so the payload fired during compilation, before any unit test or SCA gate ran. NuGet.org's open publishing model — anyone can register an account and push a package — combined with typosquatting names like "Coinbase.Core" mimicking the legitimate "Coinbase" package, gives attackers a low-cost, high-trust delivery channel directly into enterprise build systems.

What real attacks have already hit .NET dependency chains?

Real attacks have already delivered remote access trojans, credential stealers, and industrial espionage tooling through NuGet, not hypothetical malware. The JFrog-documented typosquat wave (March 2023) used names like "Coinbase.Core," "DiscordRichPresence.API," and "Anarchy.Wrapper.Net" to trigger a second-stage PowerShell download of crypto-stealing malware. In July 2024, ReversingLabs uncovered 60 additional malicious packages spanning 290 versions that used IL weaving to inject a downloader for SeroXen RAT directly into legitimate compiled PE binaries — a technique specifically chosen to evade static scanners that only inspect source-level package content. Separately, a package called SqzrFramework480, first published on January 24, 2024, was downloaded 2,999 times before researchers linked it to a campaign targeting industrial systems running cameras, machine vision, and robotic-arm control software — a signal that NuGet is now a viable initial-access vector for OT-adjacent espionage, not just commodity crimeware.

What NuGet-specific CVEs should .NET teams be tracking?

.NET teams should be tracking CVE-2024-0057, CVE-2023-29337, and CVE-2020-1340 as the three NuGet-specific advisories with the broadest blast radius. CVE-2024-0057 is a security feature bypass in .NET 6.0, 7.0, and 8.0 where a flawed X.509 chain-building routine returns an incorrect failure reason code, letting an attacker present a malformed certificate that downstream code may treat as validly signed — Microsoft's fix required updating NuGet.exe to 6.8.1, 6.7.1, or 6.6.2 depending on your baseline. CVE-2023-29337 is a remote code execution flaw in the NuGet Client itself, tied to how package content is handled during restore. CVE-2020-1340 is a NuGet Gallery spoofing vulnerability caused by insufficient sanitization of package metadata fields, which attackers could abuse to make a malicious package look more credible in search results. Unlike a typical third-party CVE in a .csproj reference, these three live in the tooling that fetches and validates every other dependency — a flaw here undermines trust in packages that are otherwise clean.

Why did the Moq SponsorLink incident change how teams think about NuGet trust?

The Moq SponsorLink incident mattered because it proved a widely trusted package — not a typosquat, the real thing — can ship undisclosed data collection without tripping a single CVE or malware signature. In August 2023, Moq (a mocking framework with well over 100 million cumulative NuGet downloads) shipped version 4.20.0 with a bundled, closed-source, obfuscated dependency called SponsorLink that read the local git config user.email, hashed it with SHA-256, and phoned it to an Azure endpoint to check GitHub Sponsors status. No malware scanner flagged it because it wasn't malware by any signature-based definition — it was an undisclosed behavior change in a transitive dependency that shipped through the exact same trusted update channel teams use for security patches. AWS publicly distanced itself from the project, backlash forced a rollback in 4.20.2, and the maintainer eventually open-sourced SponsorLink. The lesson for dependency management programs: version-pinning and CVE feeds don't catch behavioral changes bundled into a routine minor-version bump.

How do you actually manage NuGet dependency vulnerabilities day to day?

You manage NuGet dependency vulnerabilities day to day by combining built-in tooling with continuous scanning, not by relying on either alone. Starting with the .NET 8 SDK (November 2023), dotnet restore runs NuGet Audit automatically, checking every direct and transitive package against the GitHub Advisory Database and printing warnings for known CVEs — teams on .NET 6 or 7 SDKs have to opt in or run dotnet list package --vulnerable --include-transitive manually, and many haven't. Central Package Management (Directory.Packages.props), generally available since NuGet 6.2, lets a team pin every package version in one file across a multi-project solution, closing the gap where the same vulnerable Newtonsoft.Json or System.Text.Json version gets pulled in three different pinned ranges across three different .csproj files. Beyond tooling, the operational baseline is: audit on every restore in CI (not just locally), fail builds on packages with no publisher history or under 90 days of age for new direct dependencies, and generate a CycloneDX or SPDX SBOM per build so you can answer "are we exposed" in minutes the next time a NuGet-specific CVE like CVE-2024-0057 drops, instead of days.

Does a NuGet CVE alert always mean your application is exploitable?

No — a NuGet CVE alert does not always mean your application is exploitable, and treating every advisory as equally urgent is why alert fatigue drowns out the packages that actually matter. A CVE in a NuGet package's XML parsing path is irrelevant if your service never deserializes untrusted XML; a deserialization flaw in a logging library is critical if that library sits directly in your public API's request pipeline. The 2024 IL-weaving campaign is instructive here too: the payload was injected into the compiled binary itself, meaning a source-only SCA scan of the .nuspec or referenced source could miss it entirely, while a build-time and binary-level check would not. Prioritization has to be based on whether the vulnerable code path is actually reachable from your application's entry points, not just whether the package name matches a CVE database row.

How Safeguard Helps

Safeguard maps every NuGet package — direct and transitive — against your actual .NET call graph using reachability analysis, so a CVE in an unreachable code path gets deprioritized instead of paging your on-call engineer at 2 a.m. Griffin AI, Safeguard's reasoning engine, cross-references advisories like CVE-2024-0057 and known malicious-package campaigns against your build and restore telemetry to flag suspicious .targets file behavior or IL-weaving patterns before they execute in CI, not after. Safeguard generates and ingests CycloneDX/SPDX SBOMs on every build so you have a point-in-time inventory ready the moment a new NuGet advisory drops, and when a fix is available, Safeguard opens an auto-fix pull request with the patched version and Central Package Management updates pre-applied, so remediation is a review-and-merge instead of a multi-repo hunt.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.