Safeguard
Open Source Security

Compromised NuGet author accounts

NuGet maintainer accounts are the .NET supply chain's weakest link. Here's why account takeover beats typosquatting, and how to detect it before a CVE exists.

Safeguard Research Team
Research
7 min read

Maintainer credentials, not code flaws, are emerging as the weak link in the .NET software supply chain. Over the past two package-registry hardening cycles — npm's mandatory 2FA rollout for top maintainers in 2022, followed by PyPI's critical-project MFA mandate in 2023 — security teams watched attackers pivot rather than retreat. NuGet, the primary package registry for the .NET ecosystem and a dependency backbone for a large share of enterprise Windows, Azure, and financial-services software, has been slower to lock down publisher accounts. Microsoft began requiring two-factor authentication for maintainers of "popular" NuGet packages in mid-2023 and introduced federated, short-lived "Trusted Publishing" credentials via Microsoft Entra ID and GitHub Actions OIDC in 2024 — but adoption across the long tail of NuGet's roughly 400,000+ listed packages remains uneven. That gap is precisely where account-compromise attacks live, and it is why "NuGet author account compromise" has become a phrase security teams need to understand now rather than after an incident.

Why Account Takeover Beats Typosquatting

Typosquatting — publishing a package named Newtonsoft.Jsonn or AutoMappper — relies on a developer making a typing mistake. It is noisy, easy to flag with fuzzy-matching tools, and easy for registries to take down. Account takeover is quieter and far more damaging. When an attacker compromises the credentials of a legitimate, trusted maintainer, they inherit that package's entire reputation: its download count, its version history, its transitive presence in thousands of downstream .csproj and packages.lock.json files, and — critically — the implicit trust that CI/CD pipelines and developers place in a routine point release. A malicious 1.4.3 published from the real maintainer's authenticated session does not trip typosquat detectors, does not require social engineering against individual developers, and often ships to production before anyone notices the diff.

This is not a theoretical concern specific to .NET. The pattern was proven across other ecosystems: the ua-parser-js npm package was hijacked via a compromised maintainer account in October 2021 and used to push cryptomining and credential-stealing payloads to millions of installs within hours; the coa and rc npm packages suffered nearly identical takeovers weeks later; and PyPI has repeatedly seen abandoned or phished maintainer accounts repurposed to slip malicious updates into packages with years of clean history. Each of these incidents shares a signature: legitimate package, legitimate publish pipeline, compromised human.

Why NuGet Is Next in Line

Three structural factors make the .NET ecosystem an increasingly attractive target for this exact playbook.

First, enforcement lag. npm and PyPI moved first and fastest on mandatory MFA for high-impact packages, which raised the cost of account takeover in those registries. NuGet's equivalent requirement — MFA for maintainers of packages that cross download-count and dependency-fan-out thresholds — only began enforcement in August 2023, and it does not cover the thousands of mid-tier packages that sit two or three levels deep in dependency trees but are still widely referenced by enterprise applications.

Second, credential hygiene. NuGet publishing has historically relied heavily on long-lived API keys generated once and stored in CI secrets, personal password managers, or — worse — checked into build scripts. A leaked or phished API key grants an attacker the same publish rights as the legitimate maintainer, with no session, device, or behavioral anomaly to trip. Microsoft's 2024 Trusted Publishing feature, which swaps static API keys for short-lived OIDC tokens scoped to a specific GitHub Actions workflow or Azure Pipelines run, directly targets this weakness — but it is opt-in, and most existing packages have not migrated.

Third, the maintainer economics of open source haven't changed. A meaningful share of widely-depended-upon NuGet packages are maintained by one or two individuals, often unpaid, often reusing credentials across services, and often not the target of any dedicated security monitoring. Sonatype's annual State of the Software Supply Chain research has tracked a multi-year surge in malicious open source components across ecosystems — reporting well over 245,000 malicious packages identified in 2023 alone, more than the prior four years combined — and account takeover is one of the fastest-growing categories within that trend precisely because it scales: one compromised credential yields control over every downstream consumer of that package, indefinitely, until someone notices.

What Traditional Scanning Misses

Here is the part that should concern platform and AppSec teams specifically: a compromised-account release rarely shows up as a CVE. Vulnerability databases are built to catalog known flaws in code, not to flag "this specific point release was published by an attacker using stolen credentials." That means standard software composition analysis (SCA), which matches installed package versions against NVD/GHSA advisory feeds, will report the malicious version as clean — because nothing has been disclosed yet. The detection burden shifts to behavioral and provenance signals: unexpected new maintainers, publish activity from unfamiliar IP ranges or outside a package's normal release cadence, version bumps that don't correspond to a public changelog or GitHub tag, and post-install scripts or obfuscated payloads that weren't present in prior releases.

Equally important is the question every incident response team eventually asks: does this actually reach our runtime? A compromised package sitting three levels deep in a dependency tree, invoked only through a code path your application never executes, carries a very different risk profile than the same package wired directly into an authentication or payment flow. Static dependency lists and SBOMs alone can't answer that question — they tell you what's present, not what's exploitable in your specific build.

Hardening Recommendations for .NET Teams

Security and platform teams running .NET estates should treat NuGet account-compromise risk as an operational control gap, not just a registry problem:

  • Migrate to Trusted Publishing. Move CI/CD pipelines off long-lived NuGet API keys and onto Entra ID / GitHub OIDC federated credentials wherever the package is internally maintained, eliminating the static-secret attack surface entirely.
  • Enforce package signing verification. NuGet supports author and repository signing; configure nuget.config trust policies to reject unsigned or unexpectedly re-signed packages rather than accepting them silently.
  • Pin and diff, don't just upgrade. Lock exact versions in packages.lock.json, and treat any dependency bump — especially patch-level bumps to packages that rarely release — as worth a changelog and diff review before merge.
  • Monitor maintainer and publish metadata, not just package content, for anomalies: new co-maintainers, publishes outside business hours or from new infrastructure, and packages that suddenly resume activity after long dormancy.
  • Maintain a live, accurate SBOM so that when a compromised-account incident does surface — often disclosed hours or days after the malicious push — you can answer "are we exposed?" in minutes, not days of manual dependency-tree archaeology.

How Safeguard Helps

Safeguard is built for exactly this failure mode: the malicious release that no CVE feed will catch in time. Our platform continuously generates and ingests SBOMs across your .NET and polyglot repositories, so when a NuGet maintainer account compromise surfaces, you get an immediate, accurate answer to "which services pull this package, and at what version" — no manual archaeology required. Reachability analysis goes a step further, tracing whether the compromised package's code paths are actually invoked by your application, so your team can triage the handful of genuinely exploitable instances instead of chasing every mention in a dependency tree. Griffin AI, Safeguard's security reasoning engine, correlates anomalous publish signals, version-bump patterns, and package provenance changes to flag likely account-takeover activity ahead of public disclosure. And once a fix or safe version is available, Safeguard opens auto-fix pull requests directly against affected repositories, closing the gap between disclosure and remediation from days to minutes.

Never miss an update

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