
.NET 7-Fork von seal-security-nuget-demo: dieselbe CVE-2024-21907-Exploit-Geschichte, neu ausgerichtet für Kunden, die an das .NET SDK 7 gebunden sind.
Dies ist ein neu ausgerichteter Fork des kanonischen seal-security-nuget-demo (der auf net9.0 abzielt). Die Exploit-Geschichte, die Controller und die Liste der versiegelten Pakete sind identisch — nur die TargetFramework unterscheidet sich.
Er existiert, weil die meisten Unternehmenskunden nicht auf das neueste .NET SDK umsteigen können, wenn sie es brauchen. .NET 7 hat am 14. Mai 2024 das Ende des Supports erreicht, aber echte Produktionsumgebungen laufen weiterhin darauf — aus Kompatibilitäts-, Zertifizierungs- oder Betriebsgründen. Genau dafür ist Seal Security konzipiert: Wenn ein Kunde keinen Major-Versionssprung machen kann (oder will), patcht Seal die verwundbare Abhängigkeit an Ort und Stelle unter derselben Version, ohne öffentliche API-Änderungen und ohne Code-Änderungen an der Anwendung des Kunden. Diese Demo ermöglicht dieses Gespräch auf dem tatsächlichen Stack des Kunden, anstatt ihn zu bitten, zuerst net8/net9 zu installieren.
Der Fork pinnt das SDK über global.json auf 7.0.x, damit während der Demo keine versehentlichen Upgrades einschleichen.
Diese Demo-Anwendung ist eine einfache ASP.NET Core Willkommensseite, die Newtonsoft.Json 12.0.2 verwendet, um Benutzereingaben als Konfigurationsobjekt zu parsen. Die App hat ein Namensfeld — geben Sie Ihren Namen ein, klicken Sie auf Los, und sie zeigt „Welcome, alice!" an. Im Hintergrund wird die Eingabe durch JsonConvert.DeserializeObject<NestedConfig>() von Newtonsoft.Json geleitet. Das ist alles — völlig standardmäßige Verwendung einer beliebten JSON-Bibliothek.
Das Problem ist, dass Newtonsoft.Json 12.0.2 (und Versionen vor 13.0.1) CVE-2024-21907 aufweist — eine Denial-of-Service-Schwachstelle mit hohem Schweregrad und einem CVSS-Score von 7.5 (HOCH). Diese Demo zeigt, wie Seal Security die Schwachstelle an Ort und Stelle patcht, ohne ein Major-Versions-Upgrade zu erfordern.
Die Methode JsonConvert.DeserializeObject<T>() von Newtonsoft.Json kann durch konstruierte, tief verschachtelte JSON-Payloads ausgenutzt werden. Beim Deserialisieren in ein typisiertes Objekt (POCO) führt der JsonSerializerInternalReader der Bibliothek wirklich rekursive Aufrufe aus (CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal), die einen Stack-Overflow verursachen, was zum Absturz der Anwendung führt (Denial of Service).
Die App nimmt Benutzereingaben entgegen und parst sie durch Newtonsoft.Json. Wenn die Eingabe eine URL ist, ruft die App zuerst den Inhalt ab — ein realistisches Muster, das von Konfigurationsladern, API-Testern und Webhook-Empfängern verwendet wird:
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
Normale Eingabe: Geben Sie alice ein → zeigt „Welcome, alice!" an
Exploit: Fügen Sie diese URL in das Namensfeld ein und klicken Sie auf Los:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Die App erkennt, dass es sich um eine URL handelt, ruft die json-payload ab (tief verschachteltes JSON {"n":{"n":{...}}}) und deserialisiert sie durch Newtonsoft.Json in die rekursive Klasse NestedConfig — was den Stack-Overflow auslöst.
Der JsonSerializerInternalReader rekursiert für jede Verschachtelungsebene durch CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue. Bei etwa 5.000 Ebenen Tiefe wird der Thread-Stack erschöpft und die Anwendung stürzt mit einer StackOverflowException ab — der Prozess stirbt sofort (keine elegante Fehlerbehandlung möglich).
Mit dieser Schwachstelle können Angreifer:
Der öffentlich verfügbare Fix erfordert ein Upgrade auf Version 13.0.1. Das Upgraden von Major-Versionen bringt jedoch oft mit sich:
Das macht den „einfach upgraden"-Fix zu einem Projekt, das leicht Wochen an Entwicklerzeit in Anspruch nehmen kann — die Schwachstelle bleibt in der Zwischenzeit offen.
Seals gepatchte Version (12.0.2-sp1) fügt Rekursionstiefenschutz hinzu, ohne eine öffentliche API zu ändern. Der Patch:
MaxDepth-Grenzen hinzu, um unbegrenzte Rekursion zu verhindernDies ist dieselbe Minderungsstrategie, die in Newtonsoft.Json 13.0.1 angewendet und als Drop-in-Ersatz auf 12.0.2 zurückportiert wurde.
Diese Demo enthält auch andere verwundbare NuGet-Pakete, die Seal Security patchen kann:
XML External Entity (XXE)-Schwachstelle in der XML-Konfigurationsanalyse von log4net. Ein Angreifer, der die log4net-Konfigurationsdatei kontrollieren kann, kann:
Hinweis zu
System.Net.Http: Das kanonische net9-Demo enthält auch eine verwundbareSystem.Net.Http 4.3.0-Referenz für CVE-2017-0249. Wir haben sie aus diesem net7-Fork weggelassen, weilSystem.Net.Httpunter .NET 7 Teil der BCL ist und die eigenständige Paketreferenz ein rudimentäres Meta-Paket ist — es hat bekannte Randfälle mitdotnet add package --source <local-nupkg>, was genau die Art und Weise ist, wie die Seal-CLI versiegelte Versionen anwendet. Das Weglassen macht denseal fix-Schritt zuverlässig, ohne die Geschichte der Demo zu ändern (HttpClientfunktioniert weiterhin einwandfrei; die Laufzeit stellt es bereit).
Windows-CLI-Binärdateien wurden nach v0.3.238 eingestellt. v0.3.238 ist für die NuGet-Behebung unter Windows voll funktionsfähig.
Eine ausführliche Windows-Server-Installations- und Ausführungsanleitung finden Sie in README-WINDOWS-SERVER.md. Der Schnellstart unten deckt dieselben Schritte in komprimierter Form ab.
PowerShell:
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
cd seal-security-nuget-demo-net7
# Wiederherstellen (zieht von nuget.org und dem Seal-Feed — siehe nuget.config)
dotnet restore
# Erstellen und ausführen
dotnet build
dotnet run
Öffnen Sie http://localhost:5000 — die App läuft mit verwundbaren Abhängigkeiten.
Geben Sie alice in das Namensfeld ein und klicken Sie auf Los. Sie sollten sehen: „Welcome, alice!"
Fügen Sie die folgende URL in das Namensfeld ein und klicken Sie auf Los:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Ergebnis ohne Patch: Der Browser zeigt einen Fehler / Verbindungsabbruch — die App ist mit einer StackOverflowException in JsonSerializerInternalReader.CreateValueInternal abgestürzt. Der Prozess ist tot.
# (Optional — oben bereits erledigt) Abhängigkeiten zuerst wiederherstellen
dotnet restore
# Seal-CLI ausführen, um Schwachstellen zu beheben
seal fix . --mode remote -v
# Erneut wiederherstellen, um versiegelte Versionen zu ziehen
dotnet restore
# Die gepatchte App erstellen und ausführen
dotnet build
dotnet run
Die App verwendet jetzt gepatchte Versionen (Newtonsoft.Json 12.0.2-sp1, log4net 2.0.5-sp1).
Ergebnis mit Patch: Fügen Sie dieselbe Exploit-URL ein → die Seite zeigt „Blocked by Seal patch: MaxDepth of 64 has been exceeded." — Newtons gepatchtes Rekursionslimit hat die tiefe Payload abgelehnt. Der Server läuft normal weiter.
dotnet list package
Sie sollten Pakete mit dem Suffix -sp1 sehen, die auf Seal-Security-Patches hinweisen.
Der CLI-Schritt muss unmittelbar nach der Installation der Abhängigkeiten, aber vor dem finalen Build hinzugefügt werden.
# 1. Abhängigkeiten wiederherstellen
dotnet restore
# 2. <--- Seal-CLI hier ausführen
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
seal fix . --mode remote -v
# 3. Erneut wiederherstellen (um versiegelte Versionen zu erhalten)
dotnet restore
# 4. Erstellen
dotnet build
| Modus | Beschreibung |
|---|---|
all | Alle verfügbaren Fixes automatisch anwenden |
remote | Nur Fixes anwenden, die in der Seal-UI genehmigt wurden |
local | Nur Fixes anwenden, die in .seal-actions.yml definiert sind |
.seal-actions.yml in diesem Repository listet bereits die drei versiegelten Overrides für den local-Modus auf, sodass seal fix . --mode local -v offline funktioniert (benötigt dennoch ein Token für den Artefakt-Server).
nuget.config ist vorkonfiguriert, um Seal Security mit Umgebungsvariablen zu verwenden:
<configuration>
<packageSources>
<add key="Seal" value="https://nuget.sealsecurity.io/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<Seal>
<add key="Username" value="%SEAL_PROJECT%" />
<add key="ClearTextPassword" value="%SEAL_TOKEN%" />
</Seal>
</packageSourceCredentials>
</configuration>
| Variable | Beschreibung |
|---|---|
SEAL_TOKEN | Ihr Seal-Security-Zugriffstoken |
SEAL_PROJECT | Projekt-ID (z. B. nuget-demo-net7) |
Die Seal-CLI benötigt ausgehendes HTTPS (TCP 443) zu:
cli.sealsecurity.io — Scan-/Fix-Konfigurationauthorization.sealsecurity.io — Token-Validierungnuget.sealsecurity.io — versiegelte .nupkg-Downloadsd2zko6i8myndc4.cloudfront.net — CDN, das die tatsächlichen versiegelten Artefakte ausliefert (die .sealsecurity.io-Hostnamen leiten hierher um)api.nuget.org / standardmäßige nuget.org-Endpunkte — für nicht versiegelte AbhängigkeitenNach dem Öffnen der Firewall aus PowerShell verifizieren:
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
Alle sollten TcpTestSucceeded: True melden.
| Element | Warum es wichtig ist |
|---|---|
global.json pinnt SDK auf 7.0.x mit rollForward: latestFeature | Verhindert, dass Maschinen mit nebeneinander installierten net8/net9 mitten in der Demo stillschweigend das SDK wechseln. |
System.Configuration.ConfigurationManager auf 7.0.0 gepinnt | Das kanonische net9-Demo verwendet 8.0.0, das nur auf net8 abzielt und unter net7 nicht wiederhergestellt werden kann. 7.0.0 hat dieselbe API-Oberfläche, die log4net benötigt. |
NU1701 in der csproj unterdrückt | log4net 2.0.5 bewirbt ein veraltetes net4x-TFM, das .NET 7 zur Laufzeit akzeptiert, aber beim Wiederherstellen warnt. Die Warnung ist kosmetisch; die Unterdrückung hält die Build-Ausgabe während der Demo sauber. |
| Seal-CLI v0.3.238 für Windows x64 | Letzte Version mit einer Windows-Binärdatei; voll funktionsfähig für die NuGet-Behebung. Windows-Binärdateien wurden nach dieser Version eingestellt, daher keine neuere Version empfehlen. |
12.0.2-sp1 ist ein binärkompatibler Drop-in-Ersatz für 12.0.2.Pakete, die von dieser Demo verwendet werden:
| Paket | Verwundbare Version | Versiegelte Version | CVE | CVSS |
|---|---|---|---|---|
| Newtonsoft.Json | 12.0.2 | 12.0.2-sp1 | CVE-2024-21907 | 7.5 HOCH |
| log4net | 2.0.5 | 2.0.5-sp1 | CVE-2018-1285 | 9.8 KRITISCH |
Andere versiegelte NuGet-Pakete, die vom Seal-Feed verfügbar sind (nicht in dieser Demo, zur Referenz aufgeführt):
| Paket | Verwundbare Version | Versiegelte Version | CVE | CVSS |
|---|---|---|---|---|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9.8 KRITISCH |
| System.Net.Http | 4.3.0 | 4.3.0-sp1 | CVE-2017-0249 | 7.3 HOCH |
| Snappier | 1.1.0 | 1.1.0-sp1 | CVE-2023-28638 | 7.0 HOCH |
| jQuery.Validation | 1.17.0 | 1.17.0-sp1 | CVE-2021-21252 | 7.5 HOCH |
MIT-Lizenz — Details finden Sie in der LICENSE-Datei.