
.NET 7 fork of seal-security-nuget-demo: same CVE-2024-21907 exploit story, retargeted for customers locked to .NET SDK 7.
This is a retargeted fork of the canonical seal-security-nuget-demo (which targets net9.0). The exploit story, the controllers, and the sealed-package list are identical — only the TargetFramework differs.
It exists because most enterprise customers can't move to the newest .NET SDK on demand. .NET 7 reached end-of-support on May 14, 2024, but real production estates still ship on it for compatibility, certification, or operational reasons. That is precisely the case Seal Security is designed for: when a customer can't (or won't) take a major version bump, Seal patches the vulnerable dependency in place under the same version, with no public API change and no code edits to the customer's app. This demo lets that conversation happen on the customer's actual stack instead of asking them to install net8/net9 first.
The fork pins the SDK to 7.0.x via global.json so accidental upgrades don't sneak in during the demo.
This demo application is a simple ASP.NET Core welcome page that uses Newtonsoft.Json 12.0.2 to parse user input as a config object. The app has a name field — type your name, click Go, and it displays "Welcome, alice!". Under the hood it passes the input through Newtonsoft.Json's JsonConvert.DeserializeObject<NestedConfig>(). That's it — completely standard usage of a popular JSON library.
The problem is that Newtonsoft.Json 12.0.2 (and versions before 13.0.1) has CVE-2024-21907 — a high severity Denial of Service vulnerability with a CVSS score of 7.5 (HIGH). This demo shows how Seal Security patches the vulnerability in-place without requiring a major version upgrade.
Newtonsoft.Json's JsonConvert.DeserializeObject<T>() method can be exploited by crafting deeply nested JSON payloads. When deserializing into a typed object (POCO), the library's JsonSerializerInternalReader performs truly recursive calls (CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal) that cause stack overflow, leading to application crash (Denial of Service).
The app takes user input and parses it through Newtonsoft.Json. If the input is a URL, the app fetches the content first — a realistic pattern used by config loaders, API testers, and webhook receivers:
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
Normal input: Type alice → displays "Welcome, alice!"
Exploit: Paste this URL into the name field and click Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
The app detects it's a URL, fetches the json-payload (deeply nested JSON {"n":{"n":{...}}}), and deserializes it through Newtonsoft.Json into the recursive NestedConfig class — triggering the stack overflow.
The JsonSerializerInternalReader recurses through CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue for every nesting level. At ~5,000 levels deep, this exhausts the thread stack and the application crashes with a StackOverflowException — the process dies instantly (no graceful error handling possible).
With this vulnerability, attackers can:
The publicly available fix requires upgrading to version 13.0.1. However, upgrading major versions often introduces:
This makes the "just upgrade" fix a project that can easily take weeks of developer time — leaving the vulnerability open in the meantime.
Seal's patched version (12.0.2-sp1) adds recursion depth protection without changing any public API. The patch:
MaxDepth limits to prevent unbounded recursionThis is the same mitigation strategy applied in Newtonsoft.Json 13.0.1, backported to 12.0.2 as a drop-in replacement.
This demo also includes other vulnerable NuGet packages that Seal Security can patch:
XML External Entity (XXE) vulnerability in log4net's XML configuration parsing. An attacker who can control the log4net configuration file can:
Note on
System.Net.Http: The canonical net9 demo also ships a vulnerableSystem.Net.Http 4.3.0reference for CVE-2017-0249. We've omitted it from this net7 fork because on .NET 7System.Net.Httpis part of the BCL and the standalone package reference is a vestigial meta-package — it has known edge cases withdotnet add package --source <local-nupkg>, which is exactly how the Seal CLI applies sealed versions. Dropping it makes theseal fixstep reliable without changing the demo's story (HttpClientstill works fine; the runtime supplies it).
Windows CLI binaries were discontinued after v0.3.238. v0.3.238 is fully functional for NuGet remediation on Windows.
A detailed Windows Server install + run guide is in README-WINDOWS-SERVER.md. The Quick Start below covers the same steps in condensed form.
PowerShell:
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
cd seal-security-nuget-demo-net7
# Restore (pulls from nuget.org and the Seal feed — see nuget.config)
dotnet restore
# Build and run
dotnet build
dotnet run
Open http://localhost:5000 — the app is running with vulnerable dependencies.
Type alice in the name field, click Go. You should see: "Welcome, alice!"
Paste the following URL into the name field and click Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Unpatched result: Browser shows an error / connection reset — the app crashed with a StackOverflowException in JsonSerializerInternalReader.CreateValueInternal. The process is dead.
# (Optional — already done above) Restore dependencies first
dotnet restore
# Run Seal CLI to fix vulnerabilities
seal fix . --mode remote -v
# Restore again to pull sealed versions
dotnet restore
# Build and run the patched app
dotnet build
dotnet run