Safeguard
Open Source Security

NuGet package vulnerability trends report

NuGet's growing attack surface: typosquatting, steganographic malware, and patch lag are reshaping .NET supply chain risk in 2026 — here's what the data shows.

Safeguard Research Team
Research
7 min read

Malicious and vulnerable packages on NuGet, the primary registry for the .NET ecosystem, have moved from a theoretical risk to a routine finding in enterprise software composition scans. Security researchers tracking the registry through the second quarter of 2026 report a continued rise in typosquatting campaigns, steganography-based malware droppers, and slow patch adoption for known-vulnerable dependencies across widely used packages — a pattern that mirrors what npm and PyPI have already experienced at greater scale, now catching up to .NET's package ecosystem as its download volume climbs past prior-year benchmarks.

NuGet.org has surpassed 6 million unique packages and continues to log tens of billions of package downloads annually, a footprint large enough that even a small percentage of malicious or neglected packages translates into a meaningful attack surface for the enterprises, financial institutions, and government contractors that build on .NET. What makes the current moment notable isn't a single catastrophic breach — it's the accumulation of smaller signals: registry-side security mandates finally catching up to npm-style protections, recurring malware campaigns hiding payloads in image files and post-install scripts, and a persistent gap between when fixes ship and when downstream applications actually adopt them.

The Shape of the Problem: Typosquatting and Malicious Uploads

The most consistent attack pattern security teams have documented on NuGet over the past several release cycles is typosquatting combined with staged payload delivery. Threat actors register packages with names deliberately close to popular libraries — variations on names like Moq, SkiaSharp, and other high-download packages — hoping developers or automated build scripts pull the wrong dependency by a single missed character. Once installed, these packages have been observed using steganographic techniques, embedding malicious executables inside seemingly benign PNG image resources bundled with the package, which are then decoded and executed at build or runtime to evade static scanning that only inspects source and manifest files.

This technique matters because it defeats a large share of "does this package contain obviously malicious code" checks that rely on scanning source files and package metadata. A binary hidden inside an image asset, decoded only after installation, will not surface in a simple text-based or signature scan. Security researchers who first documented this pattern in the NuGet ecosystem noted download counts in the thousands before takedown — modest by npm standards, but enough to establish a foothold in CI pipelines, developer workstations, and in some cases production build servers where the package was pulled transitively through an internal tooling dependency.

Dependency confusion remains the second recurring vector. Enterprises that mix internal, privately hosted NuGet feeds with the public registry continue to expose themselves when internal package names aren't reserved on NuGet.org, allowing an attacker to publish a same-named public package with a higher version number that build tooling will prefer by default. This class of issue has been well understood since 2021, yet trends-report data continues to show organizations rediscovering it during incident response rather than through proactive registry hygiene.

NuGet.org's Registry-Side Response

To its credit, Microsoft and the .NET Foundation have accelerated registry-level defenses. NuGet.org has moved toward mandatory multi-factor authentication for maintainers of high-download packages, added support for trusted publishing via Entra ID and OIDC-based workflows that eliminate long-lived API keys as a theft target, and expanded automated malware scanning at upload time. Package signing enforcement and improved package deletion/reporting workflows have also reduced the window between a malicious upload and its removal compared to campaigns documented in 2023.

These changes track closely with what npm rolled out after its own wave of supply-chain incidents, and they represent real progress. But registry-side controls only address packages after they're published — they do nothing to shrink the population of already-published packages sitting in dependency trees with known CVEs that maintainers have not patched, or that downstream consumers have not upgraded to. That gap is where trend data shows the more persistent risk living.

Patch Lag: The Quiet Majority of NuGet Risk

Malware headlines get attention, but the bulk of NuGet-related exposure documented in scanning data comes from ordinary vulnerable dependencies that simply haven't been upgraded. Widely used libraries in the .NET ecosystem — JSON serialization, XML parsing, and HTTP client libraries among them — have shipped fixes for deserialization issues, denial-of-service conditions from uncontrolled resource consumption, and request-smuggling-adjacent flaws over the past several years. The fixes exist. Adoption in production applications lags well behind.

Several factors compound this in the .NET world specifically. Long-lived enterprise applications built on older target frameworks often can't take a patched package version without a broader framework upgrade, since many security fixes land only in the latest major version of a library rather than being backported. Internal platform teams frequently pin transitive dependency versions to avoid breaking changes, which means a vulnerable version of a package can persist deep in a dependency graph long after the direct dependency has been updated. And because a meaningful share of .NET shops are enterprises with slower release cadences than cloud-native startups, the average time-to-remediate for a disclosed NuGet CVE tends to run longer than comparable figures reported for JavaScript or Python ecosystems.

The result is a long tail of applications running years-old, publicly known-vulnerable versions of common packages — not because teams are unaware, but because the fix requires either a breaking upgrade path or manual intervention that competes with feature work for engineering time.

What This Means for Risk Teams

Taken together, the picture for security and platform teams responsible for .NET application portfolios is one of layered risk rather than a single fixable problem. Registry-side defenses are improving and reduce the odds of a fresh malicious package slipping through unnoticed, but they don't retroactively clean up dependency trees already carrying vulnerable or abandoned packages. Typosquatting and steganographic payload delivery mean source-only scanning is no longer sufficient — build-time and binary-level inspection increasingly matters. And patch lag means that vulnerability counts alone are a poor proxy for actual risk; a portfolio can carry hundreds of CVEs where only a handful are ever reachable by attacker-controlled input, while the rest sit in dead code paths that will never fire.

For teams managing hundreds or thousands of internal .NET services, the practical challenge isn't discovering that a vulnerable package exists — automated scanners are good at that now. The challenge is triage: knowing which of those findings represent genuine exploitability in the context of how the application actually calls the vulnerable code, and which are noise that would consume remediation cycles without reducing real risk.

How Safeguard Helps

Safeguard is built for exactly this triage problem in .NET and mixed-language environments. Reachability analysis traces whether a vulnerable NuGet package's flagged code path is actually invoked by application logic, so teams can prioritize the CVEs that matter instead of chasing every entry in a dependency tree. Griffin, Safeguard's AI-powered security analyst, correlates package-level findings with steganographic and behavioral indicators consistent with known malicious-package campaigns, helping teams catch supply-chain threats that source-only scanners miss. Safeguard generates and ingests SBOMs across your .NET builds to give continuous, accurate visibility into every NuGet package in production — including transitive dependencies pinned deep in the graph — and maps them against newly disclosed CVEs in real time. When a fix is available, Safeguard opens auto-fix pull requests that bump the affected package to a patched, compatible version, cutting the manual work that otherwise stalls remediation behind competing engineering priorities. Together, these capabilities turn NuGet vulnerability management from a reactive scramble after the next disclosure into a continuously managed, reachability-informed process.

Never miss an update

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