NuGet Audit Checks at Restore. cve.now Covers What's Already Running.

NuGet Audit checks your packages for known vulnerabilities every time you restore. That's the right default, but it has one blind spot: it only runs when something restores. A service you shipped last month and haven't built since isn't being audited at all. If a critical CVE lands on one of its packages today, nothing tells you until the next build, and that might be weeks away.

cve.now is a free public vulnerability feed that fills that gap. This article covers what NuGet Audit already gives you, what cve.now adds, and how to wire the two together in a .NET 10 codebase.

What NuGet Audit already does

Since the .NET 8 SDK (NuGet 6.8), restore checks every package your project uses against a vulnerability database and raises a warning per severity (Microsoft Learn):

Warning Severity
NU1901 Low
NU1902 Moderate
NU1903 High
NU1904 Critical

For nuget.org, that database is the GitHub Advisory Database. Two details are worth knowing:

  • NuGetAuditMode defaults to all, meaning transitive packages too, only when a project targets net10.0 or higher. Older targets audit direct references only unless you opt in.
  • The audit data changes even when your code doesn't. An unchanged project can start failing tomorrow because an advisory was published overnight. That's the point, but it also means the build is the only place this signal shows up.

A repository-level setup that blocks high and critical issues looks like this:

<!-- Directory.Build.props -->
<Project>
  <PropertyGroup>
    <NuGetAuditMode>all</NuGetAuditMode>
    <WarningsAsErrors>$(WarningsAsErrors);NU1903;NU1904</WarningsAsErrors>
  </PropertyGroup>
</Project>

When a warning shows up, the .NET 10 SDK can bump the affected packages for you:

dotnet package update --vulnerable

What cve.now is

cve.now merges the CVE List, the GitHub Advisory Database, OSV, NVD, ENISA's EUVD, CISA's Known Exploited Vulnerabilities (KEV) catalog, FIRST EPSS scores and Exploit-DB into one deduplicated entry per vulnerability. It publishes the result as RSS, Atom, JSON Feed, a JSON API and an MCP server. It doesn't need an account or an API key.

It's run by Sazabi. The service's source isn't public; the GitHub repository holds the docs and the issue tracker.

The NuGet feed

Everything is one endpoint with filters that combine:

https://cve.now/feed?ecosystem=nuget&filter=critical

Add &format=json or &format=atom if your reader needs it. In Slack, /feed subscribe <url> puts it in a channel. Any RSS reader works too.

The critical filter is the part I care about most. An entry qualifies if any of these is true:

  • it's in CISA KEV, meaning exploitation has been observed in the wild;
  • it has CVSS 9+ in a technology they track;
  • it has CVSS 7+ and an EPSS score of 0.1 or more. EPSS estimates the probability that a vulnerability will be exploited in the next 30 days.

CVSS tells you how bad a vulnerability would be. KEV and EPSS tell you how likely it is to be used. A 9.8 in a code path nobody can reach is less urgent than a 7.5 that's in KEV. Filtering on exploitation signals keeps the feed quiet enough that people still read it.

Asking from your editor: the MCP server

cve.now exposes a remote Streamable HTTP MCP server at https://mcp.cve.now/mcp, with no authentication. Its tools are get_vulnerability, list_feed and check_stack.

In VS Code, add it to .vscode/mcp.json:

{
  "servers": {
    "cve-now": {
      "type": "http",
      "url": "https://mcp.cve.now/mcp"
    }
  }
}

Then ask Copilot in agent mode something like "list this week's critical NuGet entries" or "look up CVE-XXXX-YYYY and tell me the fixed version".

Limits worth knowing

  • Lockfile upload doesn't list NuGet. The site can turn a lockfile into a per-stack report and feed, but the supported formats are npm, Python, Rust, Go, Ruby and Elixir lockfiles. packages.lock.json isn't on that list today, so for .NET use the ecosystem feed.
  • You're sending your stack to a third party. check_stack and the stack URLs mean sharing package names and versions. That's fine for public packages. Be careful with internal package names, which can reveal more than you'd expect.
  • Summaries are model-written. They're labeled as such, and each entry links its upstream sources. Read the advisory before deciding anything.
  • It doesn't replace NuGet Audit. The feed tells a human that something changed. The build is still what stops a vulnerable package from shipping.

Takeaway

Keep NuGet Audit in the build with high and critical as errors. That protects everything you ship from now on. Add the cve.now NuGet feed to a channel the team actually reads. That covers what you shipped last month and won't build again for a while.

Resources