
.NET 7 fork de seal-security-nuget-demo: la misma historia de exploit de CVE-2024-21907, reorientado para clientes limitados al SDK de .NET 7.
Este es un fork reorientado del demo canónico seal-security-nuget-demo (que apunta a net9.0). La historia del exploit, los controladores y la lista de paquetes sellados son idénticos — solo difiere el TargetFramework.
Existe porque la mayoría de los clientes empresariales no pueden migrar al SDK de .NET más reciente bajo demanda. .NET 7 llegó al final de su soporte el 14 de mayo de 2024, pero muchos entornos de producción reales aún dependen de él por razones de compatibilidad, certificación u operativas. Ese es precisamente el caso para el que Seal Security está diseñado: cuando un cliente no puede (o no quiere) dar un salto de versión mayor, Seal parchea la dependencia vulnerable in situ, bajo la misma versión, sin cambios en la API pública ni ediciones de código en la aplicación del cliente. Este demo permite que esa conversación ocurra sobre la pila real del cliente, en lugar de pedirle que instale primero net8/net9.
El fork fija el SDK a 7.0.x mediante global.json para que las actualizaciones accidentales no se cuelen durante el demo.
Esta aplicación de demostración es una sencilla página de bienvenida ASP.NET Core que usa Newtonsoft.Json 12.0.2 para analizar la entrada del usuario como un objeto de configuración. La aplicación tiene un campo de nombre: escribe tu nombre, haz clic en Go, y muestra "¡Bienvenido, alice!". Internamente, pasa la entrada a través de JsonConvert.DeserializeObject<NestedConfig>() de Newtonsoft.Json. Eso es todo: un uso completamente estándar de una biblioteca JSON popular.
El problema es que Newtonsoft.Json 12.0.2 (y versiones anteriores a la 13.0.1) tiene la CVE-2024-21907 — una vulnerabilidad de denegación de servicio de alta gravedad con una puntuación CVSS de 7.5 (ALTA). Este demo muestra cómo Seal Security parchea la vulnerabilidad in situ sin requerir una actualización de versión mayor.
El método JsonConvert.DeserializeObject<T>() de Newtonsoft.Json puede explotarse creando payloads JSON profundamente anidados. Al deserializar en un objeto tipado (POCO), el JsonSerializerInternalReader de la biblioteca realiza llamadas realmente recursivas (CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal) que provocan un desbordamiento de pila, lo que lleva al bloqueo de la aplicación (denegación de servicio).
La aplicación toma la entrada del usuario y la analiza mediante Newtonsoft.Json. Si la entrada es una URL, la aplicación primero obtiene el contenido — un patrón realista usado por cargadores de configuración, probadores de API y receptores de webhooks:
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
Entrada normal: Escribe alice → muestra "¡Bienvenido, alice!"
Exploit: Pega esta URL en el campo de nombre y haz clic en Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
La aplicación detecta que es una URL, obtiene el json-payload (JSON profundamente anidado {"n":{"n":{...}}}) y lo deserializa mediante Newtonsoft.Json en la clase recursiva NestedConfig — lo que desencadena el desbordamiento de pila.
El JsonSerializerInternalReader recorre recursivamente CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue para cada nivel de anidamiento. A unos ~5.000 niveles de profundidad, esto agota la pila del subproceso y la aplicación falla con una StackOverflowException — el proceso muere al instante (no es posible un manejo de errores elegante).
Con esta vulnerabilidad, los atacantes pueden:
La corrección disponible públicamente requiere actualizar a la versión 13.0.1. Sin embargo, actualizar las versiones mayores a menudo introduce:
Esto convierte la solución de "simplemente actualizar" en un proyecto que puede llevar fácilmente semanas de tiempo de desarrollo — dejando la vulnerabilidad abierta mientras tanto.
La versión parcheada de Seal (12.0.2-sp1) añade protección de profundidad de recursión sin cambiar ninguna API pública. El parche:
MaxDepth predeterminados para evitar la recursión ilimitadaEsta es la misma estrategia de mitigación aplicada en Newtonsoft.Json 13.0.1, retroportada a 12.0.2 como reemplazo directo.
Este demo también incluye otros paquetes NuGet vulnerables que Seal Security puede parchear:
Vulnerabilidad de entidad externa XML (XXE) en el análisis de la configuración XML de log4net. Un atacante que pueda controlar el archivo de configuración de log4net puede:
Nota sobre
System.Net.Http: El demo canónico de net9 también incluye una referencia vulnerable aSystem.Net.Http 4.3.0para la CVE-2017-0249. La hemos omitido en este fork de net7 porque en .NET 7System.Net.Httpforma parte de la BCL y la referencia independiente del paquete es un meta-paquete vestigial: tiene casos límite conocidos condotnet add package --source <local-nupkg>, que es exactamente como el CLI de Seal aplica las versiones selladas. Eliminarla hace que el paso deseal fixsea fiable sin cambiar la historia del demo (HttpClientsigue funcionando correctamente; el runtime lo proporciona).
Los binarios del CLI de Windows se descontinuaron después de la v0.3.238. La v0.3.238 es totalmente funcional para la remediación de NuGet en Windows.
Una guía detallada de instalación y ejecución en Windows Server está en README-WINDOWS-SERVER.md. El Inicio rápido a continuación cubre los mismos pasos en forma condensada.
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
Abre http://localhost:5000 — la aplicación se está ejecutando con dependencias vulnerables.
Escribe alice en el campo de nombre y haz clic en Go. Deberías ver: "¡Bienvenido, alice!"
Pega la siguiente URL en el campo de nombre y haz clic en Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Resultado sin parchear: El navegador muestra un error / restablecimiento de la conexión — la aplicación falló con una StackOverflowException en JsonSerializerInternalReader.CreateValueInternal. El proceso está muerto.
# (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
La aplicación ahora usa versiones parcheadas (Newtonsoft.Json 12.0.2-sp1, log4net 2.0.5-sp1).
Resultado parcheado: Pega la misma URL de exploit → la página muestra "Bloqueado por el parche de Seal: se ha superado el MaxDepth de 64." — el límite de recursión parcheado de Newtonsoft.Json rechazó el payload profundo. El servidor continúa ejecutándose con normalidad.
dotnet list package
Deberías ver paquetes con el sufijo -sp1, lo que indica los parches de Seal Security.
El paso del CLI debe añadirse inmediatamente después de instalar las dependencias pero antes de la compilación final.
# 1. Restore dependencies
dotnet restore
# 2. <--- Run Seal CLI Here
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
seal fix . --mode remote -v
# 3. Restore again (to get sealed versions)
dotnet restore
# 4. Build
dotnet build
| Modo | Descripción |
|---|---|
all | Aplicar automáticamente todas las correcciones disponibles |
remote | Aplicar solo las correcciones aprobadas en la interfaz de Seal |
local | Aplicar solo las correcciones definidas en .seal-actions.yml |
El archivo .seal-actions.yml de este repositorio ya enumera las tres sobrescrituras selladas para el modo local, por lo que seal fix . --mode local -v funciona sin conexión (aunque aún necesita el token para el servidor de artefactos).
nuget.config está preconfigurado para usar Seal Security con variables de entorno:
<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 | Descripción |
|---|---|
SEAL_TOKEN | Tu token de acceso de Seal Security |
SEAL_PROJECT | ID del proyecto (p. ej., nuget-demo-net7) |
El CLI de Seal necesita HTTPS saliente (TCP 443) hacia:
cli.sealsecurity.io — configuración de escaneo / correcciónauthorization.sealsecurity.io — validación de tokennuget.sealsecurity.io — descargas de .nupkg selladosd2zko6i8myndc4.cloudfront.net — CDN que sirve los artefactos sellados reales (los nombres de host .sealsecurity.io redirigen aquí)api.nuget.org / endpoints estándar de nuget.org — para dependencias no selladasVerifica desde PowerShell después de abrir el firewall:
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
Todos deberían mostrar TcpTestSucceeded: True.
12.0.2-sp1 es un reemplazo directo compatible a nivel binario para 12.0.2.Paquetes utilizados por este demo:
| Paquete | Versión vulnerable | Versión sellada | CVE | CVSS |
|---|
Otros paquetes NuGet sellados disponibles desde el feed de Seal (no en este demo, listados como referencia):
Licencia MIT: consulta el archivo LICENSE para obtener más detalles.
| Elemento | Por qué importa |
|---|
global.json fija el SDK a 7.0.x con rollForward: latestFeature | Evita que las máquinas con net8/net9 en paralelo cambien silenciosamente de SDK a mitad de la demo. |
System.Configuration.ConfigurationManager fijado a 7.0.0 | El demo canónico de net9 usa 8.0.0, que solo apunta a net8 y no puede restaurarse en net7. 7.0.0 tiene la misma superficie de API que necesita log4net. |
NU1701 suprimido en el csproj | log4net 2.0.5 anuncia un TFM heredado net4x que .NET 7 acepta en tiempo de ejecución, pero advierte al restaurar. La advertencia es cosmética; la supresión mantiene la salida de compilación limpia durante la demo. |
| CLI de Seal v0.3.238 para Windows x64 | Última versión con binario para Windows; totalmente funcional para la remediación de NuGet. Los binarios de Windows se descontinuaron después de esta versión, así que no sugieras una versión más reciente. |
| Newtonsoft.Json | 12.0.2 | 12.0.2-sp1 | CVE-2024-21907 | 7.5 ALTA |
| log4net | 2.0.5 | 2.0.5-sp1 | CVE-2018-1285 | 9.8 CRÍTICA |
| Paquete | Versión vulnerable | Versión sellada | CVE | CVSS |
|---|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9.8 CRÍTICA |
| System.Net.Http | 4.3.0 | 4.3.0-sp1 | CVE-2017-0249 | 7.3 ALTA |
| Snappier | 1.1.0 | 1.1.0-sp1 | CVE-2023-28638 | 7.0 ALTA |
| jQuery.Validation | 1.17.0 | 1.17.0-sp1 | CVE-2021-21252 | 7.5 ALTA |