
.NET 7 fork de seal-security-nuget-demo : même scénario d'exploitation de la CVE-2024-21907, réorienté pour les clients verrouillés sur le SDK .NET 7.
Ceci est un fork reciblé du dépôt canonique seal-security-nuget-demo (qui cible net9.0). Le scénario d'exploitation, les contrôleurs et la liste des paquets scellés sont identiques — seul le TargetFramework diffère.
Il existe parce que la plupart des clients en entreprise ne peuvent pas migrer vers le dernier SDK .NET à la demande. .NET 7 a atteint la fin de support le 14 mai 2024, mais de nombreux environnements de production tournent encore dessus pour des raisons de compatibilité, de certification ou opérationnelles. C'est précisément le cas d'usage pour lequel Seal Security est conçu : lorsqu'un client ne peut pas (ou ne veut pas) effectuer une montée de version majeure, Seal corrige la dépendance vulnérable sur place dans la même version, sans changement d'API publique ni modification de code dans l'application du client. Cette démo permet d'avoir cette conversation sur la pile technologique réelle du client au lieu de lui demander d'installer d'abord net8/net9.
Le fork épingle le SDK à 7.0.x via global.json afin que des mises à niveau accidentelles ne s'infiltrent pas pendant la démo.
Cette application de démonstration est une simple page d'accueil ASP.NET Core qui utilise Newtonsoft.Json 12.0.2 pour analyser la saisie utilisateur comme objet de configuration. L'application possède un champ de nom — saisissez votre nom, cliquez sur Go, et elle affiche « Welcome, alice! ». En coulisses, elle fait passer la saisie par JsonConvert.DeserializeObject<NestedConfig>() de Newtonsoft.Json. C'est tout — une utilisation tout à fait standard d'une bibliothèque JSON populaire.
Le problème est que Newtonsoft.Json 12.0.2 (et les versions antérieures à 13.0.1) présente CVE-2024-21907 — une vulnérabilité de déni de service de haute sévérité avec un score CVSS de 7,5 (ÉLEVÉ). Cette démo montre comment Seal Security corrige la vulnérabilité sur place sans exiger de mise à niveau de version majeure.
La méthode JsonConvert.DeserializeObject<T>() de Newtonsoft.Json peut être exploitée en créant des charges utiles JSON profondément imbriquées. Lors de la désérialisation dans un objet typé (POCO), le JsonSerializerInternalReader de la bibliothèque effectue des appels véritablement récursifs (CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal) qui provoquent un débordement de pile, entraînant le plantage de l'application (déni de service).
L'application prend la saisie utilisateur et l'analyse via Newtonsoft.Json. Si la saisie est une URL, l'application récupère d'abord le contenu — un modèle réaliste utilisé par les chargeurs de configuration, les testeurs d'API et les récepteurs de webhooks :
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
Saisie normale : Saisissez alice → affiche « Welcome, alice! »
Exploit : Collez cette URL dans le champ de nom et cliquez sur Go :
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
L'application détecte qu'il s'agit d'une URL, récupère le json-payload (JSON profondément imbriqué {"n":{"n":{...}}}), et le désérialise via Newtonsoft.Json dans la classe récursive NestedConfig — déclenchant le débordement de pile.
Le JsonSerializerInternalReader récure à travers CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue pour chaque niveau d'imbrication. À environ 5 000 niveaux de profondeur, cela épuise la pile du thread et l'application plante avec une StackOverflowException — le processus meurt instantanément (aucune gestion d'erreur gracieuse possible).
Avec cette vulnérabilité, les attaquants peuvent :
Le correctif publiquement disponible exige une mise à niveau vers la version 13.0.1. Cependant, les mises à niveau de version majeure introduisent souvent :
Cela fait du correctif « il suffit de mettre à niveau » un projet qui peut facilement prendre des semaines de temps de développement — laissant la vulnérabilité ouverte entre-temps.
La version corrigée de Seal (12.0.2-sp1) ajoute une protection de profondeur de récursion sans changer aucune API publique. Le correctif :
MaxDepth par défaut pour empêcher une récursion illimitéeC'est la même stratégie d'atténuation appliquée dans Newtonsoft.Json 13.0.1, rétroportée en 12.0.2 comme remplacement direct.
Cette démo inclut également d'autres paquets NuGet vulnérables que Seal Security peut corriger :
Vulnérabilité d'entité externe XML (XXE) dans l'analyse de configuration XML de log4net. Un attaquant qui peut contrôler le fichier de configuration log4net peut :
Note sur
System.Net.Http: La démo net9 canonique inclut également une référence vulnérableSystem.Net.Http 4.3.0pour CVE-2017-0249. Nous l'avons omise de ce fork net7 car sur .NET 7,System.Net.Httpfait partie de la BCL et la référence de paquet autonome est un méta-paquet vestigial — il présente des cas limites connus avecdotnet add package --source <local-nupkg>, ce qui est exactement la façon dont la CLI Seal applique les versions scellées. Le supprimer rend l'étapeseal fixfiable sans changer le scénario de la démo (HttpClientfonctionne toujours parfaitement ; le runtime le fournit).
Les binaires CLI Windows ont été interrompus après v0.3.238. v0.3.238 est entièrement fonctionnel pour la remédiation NuGet sur Windows.
Un guide détaillé d'installation et d'exécution sur Windows Server est disponible dans README-WINDOWS-SERVER.md. Le démarrage rapide ci-dessous couvre les mêmes étapes sous forme condensée.
PowerShell :
$env:SEAL_TOKEN = "votre-jeton-seal-ici"
$env:SEAL_PROJECT = "nuget-demo-net7"
cd seal-security-nuget-demo-net7
# Restauration (tire depuis nuget.org et le flux Seal — voir nuget.config)
dotnet restore
# Compilation et exécution
dotnet build
dotnet run
Ouvrez http://localhost:5000 — l'application tourne avec des dépendances vulnérables.
Saisissez alice dans le champ de nom, cliquez sur Go. Vous devriez voir : « Welcome, alice! »
Collez l'URL suivante dans le champ de nom et cliquez sur Go :
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Résultat non corrigé : Le navigateur affiche une erreur / une réinitialisation de connexion — l'application a planté avec une StackOverflowException dans JsonSerializerInternalReader.CreateValueInternal. Le processus est mort.
# (Facultatif — déjà fait ci-dessus) Restaurer d'abord les dépendances
dotnet restore
# Exécuter la CLI Seal pour corriger les vulnérabilités
seal fix . --mode remote -v
# Restaurer à nouveau pour récupérer les versions scellées
dotnet restore
# Compiler et exécuter l'application corrigée
dotnet build
dotnet run
L'application utilise désormais des versions corrigées (Newtonsoft.Json 12.0.2-sp1, log4net 2.0.5-sp1).
Résultat corrigé : Collez la même URL d'exploit → la page affiche « Blocked by Seal patch: MaxDepth of 64 has been exceeded. » — la limite de récursion corrigée de Newtonsoft.Json a rejeté la charge utile profonde. Le serveur continue de fonctionner normalement.
dotnet list package
Vous devriez voir des paquets avec le suffixe -sp1 indiquant les correctifs Seal Security.
L'étape CLI doit être ajoutée immédiatement après l'installation des dépendances mais avant la compilation finale.
# 1. Restaurer les dépendances
dotnet restore
# 2. <--- Exécuter la CLI Seal ici
$env:SEAL_TOKEN = "votre-jeton-seal-ici"
$env:SEAL_PROJECT = "nuget-demo-net7"
seal fix . --mode remote -v
# 3. Restaurer à nouveau (pour obtenir les versions scellées)
dotnet restore
# 4. Compiler
dotnet build
| Mode | Description |
|---|---|
all | Appliquer automatiquement tous les correctifs disponibles |
remote | Appliquer uniquement les correctifs approuvés dans l'interface Seal |
local | Appliquer uniquement les correctifs définis dans .seal-actions.yml |
.seal-actions.yml dans ce dépôt liste déjà les trois remplacements scellés pour le mode local, donc seal fix . --mode local -v fonctionne hors ligne (nécessite toujours le jeton pour le serveur d'artefacts).
nuget.config est préconfiguré pour utiliser Seal Security avec des variables d'environnement :
<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 | Description |
|---|---|
SEAL_TOKEN | Votre jeton d'accès Seal Security |
SEAL_PROJECT | ID du projet (par ex., nuget-demo-net7) |
La CLI Seal nécessite un HTTPS sortant (TCP 443) vers :
cli.sealsecurity.io — configuration d'analyse / correctionauthorization.sealsecurity.io — validation du jetonnuget.sealsecurity.io — téléchargements de .nupkg scellésd2zko6i8myndc4.cloudfront.net — CDN qui sert les artefacts scellés réels (les noms d'hôte .sealsecurity.io redirigent ici)api.nuget.org / points de terminaison nuget.org standard — pour les dépendances non scelléesVérifiez depuis PowerShell après l'ouverture du pare-feu :
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
Tous devraient rapporter TcpTestSucceeded: True.
| Élément | Pourquoi c'est important |
|---|---|
global.json épingle le SDK à 7.0.x avec rollForward: latestFeature | Empêche les machines avec net8/net9 côte à côte de basculer silencieusement de SDK en pleine démo. |
System.Configuration.ConfigurationManager épinglé à 7.0.0 | La démo net9 canonique utilise 8.0.0, qui cible uniquement net8 et échoue à la restauration sur net7. 7.0.0 a la même surface d'API dont log4net a besoin. |
NU1701 supprimé dans le csproj | log4net 2.0.5 annonce un TFM net4x hérité que .NET 7 accepte à l'exécution mais signale à la restauration. L'avertissement est cosmétique ; la suppression maintient une sortie de compilation propre pendant la démo. |
| CLI Seal v0.3.238 pour Windows x64 | Dernière version avec un binaire Windows ; entièrement fonctionnelle pour la remédiation NuGet. Les binaires Windows ont été interrompus après cette version, donc ne suggérez pas une version plus récente. |
12.0.2-sp1 est un remplacement direct compatible binaire pour 12.0.2.Paquets utilisés par cette démo :
| Paquet | Version vulnérable | Version scellée | CVE | CVSS |
|---|---|---|---|---|
| Newtonsoft.Json | 12.0.2 | 12.0.2-sp1 | CVE-2024-21907 | 7,5 ÉLEVÉ |
| log4net | 2.0.5 | 2.0.5-sp1 | CVE-2018-1285 | 9,8 CRITIQUE |
Autres paquets NuGet scellés disponibles depuis le flux Seal (pas dans cette démo, listés pour référence) :
| Paquet | Version vulnérable | Version scellée | CVE | CVSS |
|---|---|---|---|---|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9,8 CRITIQUE |
| System.Net.Http | 4.3.0 | 4.3.0-sp1 | CVE-2017-0249 | 7,3 ÉLEVÉ |
| Snappier | 1.1.0 | 1.1.0-sp1 | CVE-2023-28638 | 7,0 ÉLEVÉ |
| jQuery.Validation | 1.17.0 | 1.17.0-sp1 | CVE-2021-21252 | 7,5 ÉLEVÉ |
Licence MIT — Voir le fichier LICENSE pour plus de détails.