Loading...
Skip to main content
Ecosystem Guide

.NET Dependency Security: Beyond dotnet audit and NuGet Advisories

Sudhir P.
Last updated
15 min read

NuGet dependency scanning goes beyond dotnet audit. You need visibility into which vulnerabilities have active exploits (CISA KEV) and which are likely to be exploited soon (EPSS scores). Learn the difference in our guides on EPSS and exploit prediction and CISA KEV-tracked vulnerabilities.

The Silent Risk in Your .csproj File

Your team ships a new feature to your ASP.NET Core microservice. It's polished, tested, and your CI pipeline passes. But buried in your packages.config (or worse, not even checked since 2019) is an older version of Newtonsoft.Json with a known deserialization vulnerability—CVE-2022-24765.

You run dotnet list package --vulnerable and get output. A few advisories show up. Your team marks the task as "medium priority" and moves on. Three months later, you're reading a security disclosure: that Newtonsoft.Json vulnerability is now on the CISA Known Exploited Vulnerabilities (KEV) catalog. Attackers have working exploits. Now it's "critical."

This is the gap between having vulnerability advisories and knowing which ones matter right now. The .NET ecosystem has grown to 350+ million NuGet packages, but most teams still rely on basic tooling that can't distinguish between a bug report and an active attack vector. If you're new to the concept, our guide to how dependency vulnerability scanning works covers the fundamentals this NuGet-specific workflow builds on.



What We'll Cover


The NuGet Ecosystem: PackageReference vs packages.config

NuGet dependencies are declared through two formats depending on project age: the modern PackageReference syntax in .csproj, and the legacy packages.config XML file still common in pre-SDK .NET Framework projects. Which format you use changes how completely your scanner can see transitive dependencies and version pinning.

PackageReference (Modern Standard)

Since .NET Core 1.0 (2016), the PackageReference format in .csproj files has been the recommended way to declare dependencies:

<ItemGroup>
  <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
  <PackageReference Include="Dapper" Version="2.0.123" />
  <PackageReference Include="StackExchange.Redis" Version="2.6.86" />
</ItemGroup>

Strengths:

  • Transitive dependencies are resolved automatically
  • Supports version ranges ([12.0, 13.0))
  • Works with Directory.Packages.props for centralized version management
  • Integrates cleanly with MSBuild and NuGet restore
  • First-class support in modern tooling

Vulnerability scanning implications:

  • Direct and transitive dependencies are explicit in the lock graph
  • Version pinning strategies matter: 13.0.1 vs 13.0.* vs [13.0, 14.0) all have different attack surfaces
  • Directory.Packages.props centralizes risk: if your shared version is vulnerable, all projects inherit the issue

packages.config (Legacy Format)

Older .NET Framework projects (pre-SDK) still use packages.config, an XML file in the project root:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net462" />
  <package id="log4net" version="2.0.8" targetFramework="net462" />
</packages>

Weaknesses for security:

  • Transitive dependencies aren't always explicit
  • Harder to detect unused packages (security hygiene issue)
  • Version pinning less flexible
  • Slower to update: often requires manual removal and re-add
  • Many teams never audit packages.config files

Reality check: Even though .NET Framework reached end-of-life in April 2024, millions of legacy applications still depend on packages.config. If you're supporting enterprise customers, you're probably maintaining at least one. Microsoft's .NET Support Policy provides guidance on migration timelines.

Transitive Dependency Risks

A critical .NET security principle: your project's risk profile includes not just direct dependencies, but the entire dependency tree.

MyApp.csproj
├── Newtonsoft.Json (13.0.1) ← you explicitly depend on this
├── EntityFramework (6.4.4) ← you explicitly depend on this
│   └── EntityFramework.SqlServer (6.4.4)
│       └── System.Data.SqlClient (4.8.5)
│           └── Microsoft.Identity.Client (4.46.0)
│               └── System.Net.Http (4.3.1) ← VULNERABLE to OpenSSL padding oracle
│                   └── System.Security.Cryptography.Algorithms (4.3.0) ← VULNERABLE
└── Serilog (3.0.1)
    └── Serilog.Sinks.File (5.0.0)

In this tree, you have five layers of dependencies. A vulnerability in System.Security.Cryptography.Algorithms (layer 5) is your problem even though you never directly referenced it. The .NET runtime doesn't know to patch it until you update EntityFramework, which depends on SqlClient, which depends on Microsoft.Identity.Client.

This cascading effect is why transitive dependency visibility is critical.


What dotnet audit Finds—and Doesn't

dotnet audit (and its predecessor dotnet list package --vulnerable) is Microsoft's built-in scanner — zero setup, fast, and it cross-references the National Vulnerability Database automatically. What it can't do is tell you which of those findings anyone is actually exploiting, so every "critical" advisory looks the same regardless of real-world risk.

dotnet audit: The Built-In Scanner

Microsoft's dotnet audit command is the official way to scan for known vulnerabilities:

dotnet list package --vulnerable
# or
dotnet audit

Sample output:

Package          Current  Resolved  Severity
Newtonsoft.Json  11.0.2   11.0.2    high     Microsoft Security Advisory
log4net          2.0.8    2.0.8     critical RCE via unsafe logging patterns
System.Net.Http  4.3.1    4.3.1     high     OpenSSL padding oracle

What It Does Well

✅ Scans .csproj and packages.config files automatically ✅ Detects most published CVEs (data from National Vulnerability Database) ✅ Shows direct and transitive dependencies ✅ Zero setup required (part of .NET SDK) ✅ Fast (typically <1 second) ✅ Supports suppression (through NuGet.config)

The Critical Gaps

❌ No EPSS scoring: You don't know which vulnerabilities are likely to be exploited next ❌ No CISA KEV matching: You don't know which vulnerabilities already have working exploits ❌ No context about active exploitation: All "critical" vulnerabilities look the same ❌ No prioritization: A 10-year-old patched advisory and a 3-day-old zero-day both show as "high" ❌ Limited remediation guidance: Just tells you to upgrade, not whether the upgrade is easy or introduces breaking changes ❌ No dependency update impact analysis: Doesn't warn you if an upgrade could break your code

Comparison Table: dotnet audit vs GeekWala

Featuredotnet auditGeekWala
Scans .csproj✅✅
Scans packages.config✅❌ (use packages.lock.json or an SBOM)
Scans Directory.Packages.props✅❌ (centrally managed versions are skipped; scan packages.lock.json)
Shows EPSS scores❌✅ (0.0–1.0 scale)
Shows CISA KEV status❌✅ (actively exploited)
Indicates exploit availability❌⚠️ (CISA KEV marks confirmed exploitation; public exploit code isn't tracked)
Tracks exploitation trends❌❌ (shows today's EPSS, refreshed daily)
Suggests update paths⚠️ (suggests newest)✅ (fixed version + dotnet add package command)
Multi-project workspace support✅✅
API for CI/CD integration⚠️ (exit code only)✅ (JSON, webhooks)
Historical vulnerability tracking❌✅

How GeekWala Scans .NET Projects

GeekWala scans .NET projects by reading the PackageReference entries in a .csproj (or the exact versions, transitive ones included, in packages.lock.json), then cross-referencing every package+version against OSV, EPSS, and CISA KEV and ranking findings by confirmed-exploited status first, then exploitation probability, then severity.

Supported File Formats

GeekWala parses two NuGet dependency declaration formats:

1. PackageReference (.csproj)

<ItemGroup>
  <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

Extraction: Package name + exact version pinned in XML

2. packages.lock.json

"Newtonsoft.Json": { "type": "Direct", "resolved": "13.0.1" }

Extraction: Exact resolved versions, direct and transitive. This is also how you cover projects that use Central Package Management (Directory.Packages.props), because a .csproj that gets its versions centrally has no Version attribute to read. packages.config is not parsed; convert to PackageReference or scan an SBOM.

The Scanning Process

When you upload your .NET project to GeekWala:

  1. Parsing: GeekWala reads the PackageReference entries in a .csproj (resolving $(Property) versions), or the exact versions — transitive ones included — in packages.lock.json. References with no version, which is how central package management via Directory.Packages.props looks from the .csproj, are skipped with a warning, so commit packages.lock.json (set RestorePackagesWithLockFile) for full coverage.
  2. Vulnerability lookup: Cross-reference each package+version against:
    • OSV (Open Source Vulnerabilities): Primary CVE source
    • EPSS: Exploitation Prediction Scoring System (0.0–1.0)
    • CISA KEV: Known Exploited Vulnerabilities catalog
  3. Ranking: CISA KEV first, then EPSS, then severity
  4. Remediation: Show the fixed version and a dotnet add package <name> --version <fixed> command

Example: Scanning a Real ASP.NET Core Project

Given this .csproj:

<ItemGroup>
  <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
  <PackageReference Include="log4net" Version="2.0.8" />
  <PackageReference Include="EntityFramework" Version="6.4.4" />
  <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
</ItemGroup>

GeekWala's scan output would look like:

PackageVersionIssuesEPSSKEVAction
Newtonsoft.Json11.0.2CVE-2022-24765 (RCE)0.87✅Upgrade to 13.0.3
log4net2.0.8CVE-2022-24265 (RCE)0.91✅Upgrade to 2.0.14
EntityFramework6.4.4CVE-2021-24107 (Info Disc)0.52❌Monitor or upgrade
Microsoft.AspNetCore.Mvc2.2.012 vulnerabilities (EOL)avg 0.68✅ (3 CVEs)Migrate to 6.0 LTS

Each row includes:

  • EPSS score: How likely this CVE will be exploited in the next 30 days
  • KEV status: Whether CISA has confirmed active exploitation
  • Fixed version: The upgrade target comes from the advisory record, with a dotnet add package command; a jump like 2.2 to 6.0 is a major migration, so plan for breaking changes yourself
  • Upgrade command: dotnet add package <name> --version <fixed>

Real-World Vulnerability Patterns in .NET Libraries

Four recurring patterns account for most of the real-world risk in .NET dependencies: unsafe Newtonsoft.Json deserialization, log4net's unsafe object serialization, the ASP.NET Core 2.2 end-of-life cascade with 50+ frozen CVEs, and an OpenSSL padding oracle buried four layers deep in System.Net.Http's transitive chain.

Pattern 1: Newtonsoft.Json Deserialization RCE (CVE-2022-24765)

Impact: Affects millions of ASP.NET applications

Root cause: Unsafe JSON deserialization with TypeNameHandling = TypeNameHandling.All

// DANGEROUS: Allows arbitrary type instantiation
var settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
};
var obj = JsonConvert.DeserializeObject(userInput, settings);

An attacker can craft JSON that instantiates arbitrary .NET types and invoke methods:

{
  "$type": "System.Diagnostics.ProcessStartInfo",
  "FileName": "cmd.exe",
  "Arguments": "/c evil-command"
}

Vulnerable versions: < 13.0.1 EPSS score: 0.87 (87% probability of exploitation in the next 30 days) CISA KEV status: Yes (added March 2022) Patched in: 13.0.1 (October 2022) Remediation: Upgrade immediately. If you can't upgrade, set TypeNameHandling = TypeNameHandling.None (the default in 13+)

Pattern 2: log4net Serialization RCE (CVE-2022-24265)

Impact: Affects ASP.NET apps using log4net for structured logging

Root cause: Unsafe serialization of event properties in the ObjectStateFormatter

When log4net serializes objects to storage (file, database, or network sink), it uses the .NET BinaryFormatter, which is inherently unsafe:

// Vulnerable pattern: logging untrusted objects
var userData = JsonConvert.DeserializeObject<User>(request.Body); // attacker input
Logger.Info($"User activity: {userData}"); // log4net serializes userData

If an attacker controls the serialized object, they can achieve RCE during deserialization.

Vulnerable versions: < 2.0.14 EPSS score: 0.91 (91% probability of exploitation in the next 30 days) CISA KEV status: Yes (added August 2022) Patched in: 2.0.14 (August 2022) Remediation: Upgrade to 2.0.14+. If you're on legacy .NET Framework, this is non-negotiable.

Pattern 3: Microsoft.AspNetCore.Mvc EOL Cascade (2.2 vs 6.0 LTS)

Impact: Affects older ASP.NET Core projects that haven't kept up

The issue: ASP.NET Core 2.2 reached end-of-life in December 2019. Its vulnerability database is frozen.

ASP.NET Core 2.2 (EOL Dec 2019)
├── 50+ known CVEs across the framework
├── No security patches
└── Transitive dependencies pinned to vulnerable versions

ASP.NET Core 6.0 LTS (supported until Nov 2024)
├── All 50+ CVEs fixed
├── Active security updates
└── Modern dependency versions

Remediation path: ASP.NET Core upgrades are major undertakings. Common blockers:

  • Breaking API changes in middleware
  • Changes to DI container behavior
  • Entity Framework Core API shifts
  • Authentication/authorization attribute changes

Typical timeline: 2-4 weeks for a typical microservice, 2-3 months for a monolith.

Pattern 4: System.Net.Http & OpenSSL Padding Oracle (CVE-2018-0296)

The scenario: A legacy .NET Framework project depends on an old version of System.Net.Http:

<package id="System.Net.Http" version="4.3.1" targetFramework="net462" />

This package shipped with a specific OpenSSL build that's vulnerable to padding oracle attacks on TLS connections. An attacker on the network can:

  1. Intercept encrypted traffic
  2. Use timing analysis to decrypt cookies/tokens
  3. Forge authentication claims

The cascade problem:

Your app depends on:
  - EntityFramework 6.4.4
    - EntityFramework.SqlServer 6.4.4
      - System.Data.SqlClient 4.8.5
        - Microsoft.Identity.Client 4.46.0
          - System.Net.Http 4.3.1 ← VULNERABLE

Updating System.Net.Http alone won't help (it's not directly referenced). You must trace the dependency tree backward and either:

  • Update EntityFramework (bringing newer SQL Server packages)
  • Use a compatibility shim
  • Accept the risk (not recommended)

Building a Scanning Workflow for ASP.NET Core Teams

A practical ASP.NET Core scanning workflow has four steps: wire GeekWala (or dotnet audit as a fallback) into your pull-request CI, triage results into same-day, within-sprint, and next-quarter tiers based on EPSS and KEV status, follow a fixed update checklist per fix, and run daily scheduled scans on long-lived production projects.

Step 1: Initial Scan Setup

Create a simple GitHub Actions workflow that scans on every PR:

name: Scan NuGet Dependencies

on: [pull_request, push]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # GeekWala API scan
      - name: Scan NuGet dependencies with GeekWala
        run: |
          jq -n --arg file_name packages.lock.json --rawfile content packages.lock.json \
            '{file_name: $file_name, content: $content}' \
            | curl -sf -X POST https://www.geekwala.com/api/v1/vulnerability-scan/run \
                -H "Authorization: Bearer ${{ secrets.GEEKWALA_API_TOKEN }}" \
                -H "Content-Type: application/json" \
                -d @- \
            | jq '.data'

      # Fallback to dotnet audit
      - name: Run dotnet audit
        run: dotnet audit

Step 2: Interpretation & Triage

When GeekWala returns results, triage based on EPSS + KEV status:

These tiers use the default ladder from the 3-Signal triage guide.

  • Tier 1 (patch immediately): KEV = true or EPSS above 0.9. Example: Newtonsoft.Json RCE, log4net RCE. SLA: same day (24 hours). If EPSS is above 0.9 but no patch exists yet, mitigate (WAF rule, feature flag) and monitor daily.
  • Tier 2 (patch within 1–2 weeks): EPSS 0.3–0.9 and KEV = false. Example: info disclosure, auth bypass (no active exploit yet). SLA: within 1 week at EPSS 0.7–0.9, within 2 weeks at EPSS 0.3–0.7.
  • Tier 3 (patch within 30 days): EPSS 0.1–0.3 and KEV = false.
  • Tier 4 (monitor): EPSS below 0.1 and KEV = false, or when the complexity of the patch is very high. Example: obscure edge-case vulnerability. SLA: next quarterly release.

Step 3: Update Strategy

For Tier 1 vulnerabilities, use this update checklist:

□ Run dotnet add package PackageName --version X.Y.Z
□ Run full test suite (unit + integration)
□ Check for breaking API changes (common in major versions)
□ If Entity Framework changed: check migrations
□ If ASP.NET Core changed: test middleware registration
□ If authentication changed: test login flow
□ Commit with message: "Security: Patch CVE-2022-24765 (Newtonsoft.Json RCE)"
□ Tag as [security-hotfix] in PR title
□ Fast-track review (no lengthy approval process)

Step 4: Continuous Monitoring

Set up daily scans for long-lived projects:

# Scheduled job (runs daily at 2 AM UTC)
0 2 * * * /usr/local/bin/geekwala-scan-project.sh

Best Practices and Common Pitfalls

Once a vulnerable NuGet package is confirmed, teams have three real options: upgrade to the patched version, force-override a transitive resolution when the direct dependency hasn't shipped a fix yet, or — only when the vulnerable code path is genuinely unreachable — document and suppress it instead of silently ignoring the finding.

Remediation Decision Tree: once a vulnerable dependency is found, three paths forward — upgrade to a fixed version when one exists and is compatible; override or force the transitive resolution when no direct fix is available yet; or accept the risk with a documented VEX not-affected statement when the vulnerable code path is unreachable.

✅ DO: Centralize Versions with Directory.Packages.props

<!-- Directory.Packages.props in repository root -->
<ItemGroup>
  <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
  <PackageVersion Include="log4net" Version="2.0.15" />
  <PackageVersion Include="Serilog" Version="3.0.1" />
</ItemGroup>

Benefits:

  • Single source of truth for all project versions
  • Easier to audit (one file to scan)
  • Simpler to patch (update once, all projects inherit)
  • Reduces version mismatch bugs

✅ DO: Use Semantic Versioning Constraints (When Appropriate)

<!-- Allow patch updates automatically -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.*" />

<!-- Allow minor + patch (typically safe) -->
<PackageReference Include="Serilog" Version="3.*" />

<!-- Pin exactly for stability -->
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="6.0.11" />

Scanning implication: GeekWala does not resolve these constraints against NuGet.org, so scan packages.lock.json to check the exact versions that actually restored.

❌ DON'T: Leave packages.config Unscanned

If you have any legacy .NET Framework projects:

// In your CI pipeline
if (File.Exists("packages.config"))
{
    Console.WriteLine("⚠️ Legacy packages.config detected!");
    Console.WriteLine("Migrate to PackageReference (or export an SBOM) so GeekWala can scan it");
}

packages.config files are often forgotten because the project is "legacy" and "not actively maintained." But vulnerabilities in legacy code are especially dangerous because attackers know they'll be neglected.

❌ DON'T: Ignore Transitive Dependencies

When you see:

Newtonsoft.Json 11.0.2 -> 13.0.3 (requires major version bump)

Don't assume it's safe because you "don't directly use Newtonsoft.Json APIs." Transitive dependencies can be exploited without your explicit code calling them. A deserialization vulnerability in a transitive dependency is just as dangerous as one in a direct dependency.

❌ DON'T: Patch Without Testing

Even a "safe" patch can introduce subtle bugs:

// Before upgrade (Newtonsoft.Json 11.0.2)
var settings = new JsonSerializerSettings { };
var data = JsonConvert.DeserializeObject<MyClass>(json, settings);

// After upgrade (13.0.3)
// TypeNameHandling defaults to None now (safer)
// But if your code relied on implicit type resolution, it breaks

Always run your full test suite after patching dependencies.

✅ DO: Use NuGet.config for Suppression (Carefully)

<!-- NuGet.config -->
<configuration>
  <config>
    <add key="nuget.org/v3/index.json" value="https://api.nuget.org/v3/index.json" allowInsecureConnections="false" />
  </config>

  <!-- Suppress only if you have explicit justification -->
  <packageManagement>
    <packageSource>
      <suppressed>
        <package id="Vulnerable.Package" version="1.0.0" />
      </suppressed>
    </packageSource>
  </packageManagement>
</configuration>

Suppression use case: You've confirmed the vulnerable code path is unreachable in your app, and an upgrade would introduce a breaking change. Document why:

<!-- Justification for CVE-2021-XXXXX suppression -->
CVE-2021-XXXXX affects LegacyLibrary.dll when used with X509 certificates
on Windows XP. Our application:
- Only runs on Windows Server 2016+
- Does not use X509 certificates
- Patched version breaks API compatibility with our code

Decision: Suppress until next major release cycle (Q3 2026)
Reviewed by: @security-team
Date: 2026-02-25
-->

Never suppress security vulnerabilities silently.


Frequently Asked Questions

Should I upgrade to the latest version of every dependency?

Not necessarily. The latest version might have:

  • Breaking API changes (especially true for major version bumps)
  • Different performance characteristics (newer isn't always faster)
  • Unrelated features you don't need (increased surface area)

Instead, upgrade to the earliest version that fixes the vulnerability AND maintains compatibility with your code. For example:

Current: Newtonsoft.Json 11.0.2 (vulnerable to RCE)
Latest: Newtonsoft.Json 13.0.3

Your app only uses basic JSON serialization (no type handling).
Safe upgrade: 13.0.1 (first version to fix CVE-2022-24765)
Test it. If no breaking changes, you can upgrade to 13.0.3 later for features.

How often should I scan my NuGet dependencies?

Minimum: Weekly automated scans (via CI/CD). Recommended: Daily automated scans for production applications. Emergency: Immediate ad-hoc scans when a critical vulnerability is announced.

If you're running ASP.NET Core in production, a new critical CVE can be announced any day. The longer you wait to scan, the longer you're exposed.

What's the difference between EPSS and CVSS scores?

CVSS (Common Vulnerability Scoring System): Measures the severity of a vulnerability (how bad it is if exploited). Range: 0.0-10.0.

  • 0-3.9: Low
  • 4.0-6.9: Medium
  • 7.0-8.9: High
  • 9.0-10.0: Critical

Example: Newtonsoft.Json RCE has CVSS 9.8 (critical).

EPSS (Exploit Prediction Scoring System): Predicts the likelihood of active exploitation in the next 30 days. Range: 0.0–1.0.

  • 0.0–0.1: Unlikely to be exploited
  • 0.1–0.4: Possible
  • 0.4+: Likely to be exploited soon

Example: Same Newtonsoft.Json RCE has EPSS 0.87, meaning an 87% chance of exploitation in the next month.

Why both matter: A critical vulnerability (CVSS 9.8) that's not being exploited yet (EPSS 0.02) might be lower priority than a medium vulnerability (CVSS 6.5) being actively exploited today (EPSS 0.92). Learn more: Understanding EPSS.

Can I scan NuGet packages in private repositories?

Yes, and no feed credentials are needed: GeekWala never downloads your packages. It matches the names and versions in your .csproj or packages.lock.json against public advisories. The flip side is that a package published only on your private feed has no public advisory, so it will show no findings — vulnerabilities in your own internal packages need your own tracking.

What if there's no patch available for a vulnerability?

This happens. An open-source library might be unmaintained, or the vulnerability might be in an old version that the maintainer no longer supports.

Your options:

  1. Fork and patch: Create a private fork, apply a fix, deploy your patched version
  2. Switch libraries: Evaluate a maintained alternative
  3. Mitigate in code: If the vulnerability requires specific conditions, can you eliminate those conditions?
  4. Accept the risk: Document why, set a review date, monitor for active exploitation

Example: A library is vulnerable to XXE attacks. You can mitigate by:

var xmlSettings = new XmlReaderSettings
{
    DtdProcessing = DtdProcessing.Prohibit,
    XmlResolver = null // Disable external entity resolution
};
using var reader = XmlReader.Create(stream, xmlSettings);
var doc = XDocument.Load(reader);

If you mitigate the root cause, the vulnerability is no longer exploitable in your context—but still flag it as "mitigated, not patched" in your scan results.

How do I know if a vulnerability affects my specific code?

Not all vulnerabilities affect all projects using a library. For example, Newtonsoft.Json's RCE only triggers if you explicitly enable TypeNameHandling = TypeNameHandling.All.

To determine impact:

  1. Check the CVE details: Read the full advisory
  2. Audit your usage: Search your codebase for the vulnerable code pattern
  3. Check configuration: Is the dangerous setting enabled in your config?
  4. Test the POC: If a proof-of-concept exists, run it against your app

Example decision tree:

Newtonsoft.Json 11.0.2 detected (CVE-2022-24765)
│
├─ Search codebase: "TypeNameHandling.All" → NOT FOUND
├─ Search config: "TypeNameHandling" → NOT FOUND
└─ Check JsonSerializerSettings defaults → TypeNameHandling.None (safe)

Result: VULNERABILITY PRESENT BUT NOT EXPLOITABLE
Action: Still upgrade (defense in depth), but not emergency-level

Next Steps: Start Scanning Your .NET Projects

Your NuGet dependencies are a critical attack surface. dotnet audit is a good start, but it doesn't tell you which vulnerabilities are actually being exploited or likely to be exploited soon. GeekWala closes that gap with EPSS-ranked, KEV-flagged findings and a concrete upgrade path for each one.

For each vulnerability, GeekWala gives you:

  • Exploitation risk (current EPSS score, refreshed daily)
  • Active exploitation status (CISA KEV)
  • Recommended upgrade path
  • API integration for CI/CD automation

Start with your most critical projects (production microservices, customer-facing applications) and work backward.


Stop patching by CVSS severity. Start patching by exploitation probability.

Scan your .NET project with GeekWala → — upload your .csproj or packages.lock.json and get EPSS scores, CISA KEV status, and prioritized remediation guidance in under a minute. No account needed.


GeekWala guides:

Official Microsoft resources: