## https://sploitus.com/exploit?id=4555AEDE-8A3F-56B2-BD18-AB1D3D2B6092
# Browser + CLI Demo (NuGet/C#) โ .NET 7 Edition
## Why a .NET 7 fork?
This is a retargeted fork of the canonical [`seal-security-nuget-demo`](https://github.com/seal-sec-demo-2/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.
---
## Overview
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()`. 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.
---
## The Vulnerability: CVE-2024-21907
### What is the vulnerability?
Newtonsoft.Json's `JsonConvert.DeserializeObject()` 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).
### How the exploit works
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:
```csharp
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject(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](https://github.com/seal-sec-demo-2/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).
### Real-world impact
With this vulnerability, attackers can:
- **Crash the application** by sending malicious JSON payloads
- **Cause Denial of Service** affecting all users
- **Exhaust server resources** through repeated exploitation
- **Bypass rate limiting** since each request crashes the process
### Why not just upgrade to Newtonsoft.Json 13.0.1?
The publicly available fix requires upgrading to version 13.0.1. However, upgrading major versions often introduces:
- **Breaking API changes** in serialization behavior
- **Compatibility issues** with other libraries expecting specific versions
- **Extensive testing requirements** for all serialization/deserialization code paths
- **Risk of runtime behavior changes** in production
This makes the "just upgrade" fix a project that can easily take **weeks of developer time** โ leaving the vulnerability open in the meantime.
### How Seal Security fixes it
Seal's patched version (`12.0.2-sp1`) adds **recursion depth protection** without changing any public API. The patch:
1. Adds default `MaxDepth` limits to prevent unbounded recursion
2. Gracefully handles deep nesting with proper exceptions instead of stack overflow
3. **Does not change any public API** โ existing code continues to work without modification
This is the same mitigation strategy applied in Newtonsoft.Json 13.0.1, backported to 12.0.2 as a drop-in replacement.
---
## Other Vulnerable Dependencies
This demo also includes other vulnerable NuGet packages that Seal Security can patch:
### log4net 2.0.5 - CVE-2018-1285 (CVSS 9.8 CRITICAL)
**XML External Entity (XXE) vulnerability** in log4net's XML configuration parsing. An attacker who can control the log4net configuration file can:
- Read arbitrary files from the server
- Perform Server-Side Request Forgery (SSRF)
- Cause Denial of Service
> **Note on `System.Net.Http`:** The canonical net9 demo also ships a vulnerable `System.Net.Http 4.3.0` reference for CVE-2017-0249. We've omitted it from this net7 fork because on .NET 7 `System.Net.Http` is part of the BCL and the standalone package reference is a vestigial meta-package โ it has known edge cases with `dotnet add package --source `, which is exactly how the Seal CLI applies sealed versions. Dropping it makes the `seal fix` step reliable without changing the demo's story (`HttpClient` still works fine; the runtime supplies it).
---
## Prerequisites
- **.NET 7.0 SDK** ([download from Microsoft](https://dotnet.microsoft.com/download/dotnet/7.0))
- **Seal Security CLI v0.3.238** for Windows x64 ([direct download](https://github.com/seal-community/cli/releases/download/v0.3.238/seal-windows-amd64-v0.3.238.exe))
> Windows CLI binaries were discontinued after v0.3.238. v0.3.238 is fully functional for NuGet remediation on Windows.
- Seal Security Token (from the Seal dashboard)
A detailed Windows Server install + run guide is in [`README-WINDOWS-SERVER.md`](README-WINDOWS-SERVER.md). The Quick Start below covers the same steps in condensed form.
---
## Quick Start (Local Windows Server)
### 1. Set Environment Variables
PowerShell:
```powershell
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
```
### 2. Run the Vulnerable App (Before Seal)
```powershell
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](http://localhost:5000) โ the app is running with vulnerable dependencies.
#### Test with normal input
Type `alice` in the name field, click **Go**. You should see: **"Welcome, alice!"**
#### Test with exploit payload
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.
### 3. Apply Seal Security Fix
```powershell
# (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
```
The app now uses patched versions (`Newtonsoft.Json 12.0.2-sp1`, `log4net 2.0.5-sp1`).
**Patched result:** Paste the same exploit URL โ the page shows **"Blocked by Seal patch: MaxDepth of 64 has been exceeded."** โ Newtonsoft.Json's patched recursion limit rejected the deep payload. The server continues running normally.
### 4. Verify Patched Versions
```powershell
dotnet list package
```
You should see packages with `-sp1` suffix indicating Seal Security patches.
---
## Seal Security CLI Integration
### The Golden Rule
The CLI step must be added **immediately after dependencies are installed** but **before the final build**.
```powershell
# 1. Restore dependencies
dotnet restore
# 2.
```
### Required Environment Variables
| Variable | Description |
|----------|-------------|
| `SEAL_TOKEN` | Your Seal Security access token |
| `SEAL_PROJECT` | Project ID (e.g., `nuget-demo-net7`) |
### Network Allowlist (for restricted environments)
The Seal CLI needs outbound HTTPS (TCP 443) to:
- `cli.sealsecurity.io` โ scan / fix configuration
- `authorization.sealsecurity.io` โ token validation
- `nuget.sealsecurity.io` โ sealed `.nupkg` downloads
- `d2zko6i8myndc4.cloudfront.net` โ CDN that serves the actual sealed artifacts (the `.sealsecurity.io` hostnames redirect here)
- `api.nuget.org` / standard nuget.org endpoints โ for non-sealed dependencies
Verify from PowerShell after the firewall is opened:
```powershell
Test-NetConnection cli.sealsecurity.io -Port 443
Test-NetConnection authorization.sealsecurity.io -Port 443
Test-NetConnection nuget.sealsecurity.io -Port 443
Test-NetConnection d2zko6i8myndc4.cloudfront.net -Port 443
```
All should report `TcpTestSucceeded: True`.
---
## .NET 7-Specific Notes
| Item | Why it matters |
|------|----------------|
| `global.json` pins SDK to `7.0.x` with `rollForward: latestFeature` | Stops machines with side-by-side net8/net9 from silently switching SDKs mid-demo. |
| `System.Configuration.ConfigurationManager` pinned to **7.0.0** | The canonical net9 demo uses 8.0.0, which targets net8 only and fails to restore on net7. 7.0.0 has the same API surface log4net needs. |
| `NU1701` suppressed in the csproj | `log4net 2.0.5` advertises a legacy `net4x` TFM that .NET 7 accepts at runtime but warns about at restore. The warning is cosmetic; suppression keeps build output clean during the demo. |
| Seal CLI **v0.3.238** for Windows x64 | Last release with a Windows binary; fully functional for NuGet remediation. Windows binaries were discontinued after this version, so do not suggest a newer release. |
---
## Demo Talking Points
* **No code changes** โ the application code is identical to the unpatched version. Only the NuGet package version was swapped.
* **Same API** โ `12.0.2-sp1` is a binary-compatible drop-in for `12.0.2`.
* **Targets the customer's actual stack** โ net7.0, not net9.0. No SDK upgrade required.
* **Defense in depth** โ protects all code paths, including transitive dependencies.
* **Public patches** โ all patches are open source and auditable.
* **EOL .NET still gets patched** โ this is the core value: Microsoft no longer ships security updates for .NET 7, but Seal keeps a customer's existing dependency surface secure.
---
## Available Sealed NuGet Packages
Packages used by **this demo**:
| Package | Vulnerable Version | Sealed Version | CVE | CVSS |
|---------|-------------------|----------------|-----|------|
| Newtonsoft.Json | 12.0.2 | 12.0.2-sp1 | CVE-2024-21907 | 7.5 HIGH |
| log4net | 2.0.5 | 2.0.5-sp1 | CVE-2018-1285 | 9.8 CRITICAL |
Other sealed NuGet packages available from the Seal feed (not in this demo, listed for reference):
| Package | Vulnerable Version | Sealed Version | CVE | CVSS |
|---------|-------------------|----------------|-----|------|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9.8 CRITICAL |
| System.Net.Http | 4.3.0 | 4.3.0-sp1 | CVE-2017-0249 | 7.3 HIGH |
| Snappier | 1.1.0 | 1.1.0-sp1 | CVE-2023-28638 | 7.0 HIGH |
| jQuery.Validation | 1.17.0 | 1.17.0-sp1 | CVE-2021-21252 | 7.5 HIGH |
---
## License
MIT License - See LICENSE file for details.