DEV Community

Cover image for CVE-2026-40372: parche de emergencia de Microsoft para ASP.NET Core Data Protection
lu1tr0n
lu1tr0n

Posted on • Originally published at elsolitario.org

CVE-2026-40372: parche de emergencia de Microsoft para ASP.NET Core Data Protection

El 21 de abril de 2026, Microsoft publicó un parche de emergencia fuera de ciclo (out-of-band) para ASP.NET Core Data Protection, el subsistema que maneja cookies cifradas, antiforgery tokens y el resto de payloads autenticados en cualquier aplicación .NET moderna. La vulnerabilidad, catalogada como CVE-2026-40372, afecta al paquete NuGet Microsoft.AspNetCore.DataProtection en versiones 10.0.0 a 10.0.6 y permite a un atacante no autenticado forjar payloads autenticados saltando la validación HMAC. Microsoft le asigna CVSS 9.1 (HIGH) y obliga a actualizar a 10.0.7 de inmediato.

Lo más inquietante no es la nota CVSS ni la severidad abstracta, sino la naturaleza del bug: es una regresión introducida en las versiones 10.x de un paquete que forma parte del core de ASP.NET. Microsoft lo descubrió porque varios clientes reportaron fallos de descifrado en apps migradas a la nueva versión; al investigar, encontraron que el encryptor autenticado calculaba el tag HMAC sobre los bytes equivocados del payload y luego descartaba el hash calculado. Un atacante que entienda el fallo puede producir payloads que pasen la verificación sin tener la llave. Este artículo analiza qué quebró exactamente, quiénes están afectados, cómo verificar tu aplicación y por qué los bugs en código criptográfico son particularmente peligrosos.

Qué es ASP.NET Core Data Protection y por qué importa

El sistema Data Protection es la librería estándar que ASP.NET Core usa para cifrar y firmar cualquier dato que deba sobrevivir un round-trip por el navegador o entre procesos. Si tu aplicación usa cookies de autenticación, tokens antiforgery, CSRF tokens, Identity Framework, Blazor Server, SignalR o almacenamiento temporal entre componentes, estás usando Data Protection aunque no lo hayas llamado explícitamente. La mayoría de los desarrolladores nunca interactúa con la API directamente: el framework la invoca por debajo.

El subsistema provee dos garantías criptográficas clave: confidencialidad (los datos están cifrados y no pueden ser leídos por el cliente) e integridad autenticada (los datos no pueden ser modificados por el cliente sin que el servidor lo detecte). Esa segunda garantía se implementa con HMAC: al emitir un payload, el servidor calcula un tag HMAC sobre el contenido y lo adjunta; al recibirlo, vuelve a calcular el tag y lo compara con el que llegó. Si los tags difieren, el payload se rechaza. Es el mecanismo que evita que un cliente manipule el valor de su cookie de sesión o forje un CSRF token.

HMAC validation: el mecanismo que CVE-2026-40372 rompe en las versiones 10.0.0 a 10.0.6.

El bug: computar HMAC sobre bytes equivocados

Según la descripción oficial publicada por Microsoft y recogida en Ars Technica, el problema se introdujo en el managed authenticated encryptor de las versiones 10.x: al encriptar y autenticar un payload, la implementación nueva calculaba su tag HMAC sobre los bytes equivocados del payload y luego descartaba el hash computado. El texto literal de Microsoft describe la condición como una regresión que resulta en elevation of privilege.

Traducido a consecuencias prácticas: el servidor genera un tag que no cubre lo que se supone debe cubrir, y al validar acepta como válidos payloads que nunca fueron firmados correctamente. Un atacante que comprenda el gap puede construir datos arbitrarios que el servidor interpretará como emitidos por sí mismo. En el contexto de una cookie de sesión, eso significa poder forjar sesiones válidas sin conocer ninguna llave. En el contexto de un antiforgery token, significa poder generar tokens que pasen validación. En el contexto de Identity Framework, significa poder construir tickets de autenticación que el servidor aceptará como legítimos.

flowchart LR
  A["Atacante sin credenciales"] --> B["Construye payload manipulado"]
  B --> C["Calcula tag HMAC usando gap del bug"]
  C --> D["Envía al servidor vulnerable 10.0.0-10.0.6"]
  D --> E["Servidor valida HMAC sobre bytes equivocados"]
  E --> F["Payload aceptado como legítimo"]
  F --> G["Elevation of privilege"]
Enter fullscreen mode Exit fullscreen mode

⚠️ Ojo: el bug afecta al encryptor managed (implementación gestionada). Las implementaciones nativas de algunos escenarios no están afectadas, pero la mayoría de las apps modernas usan el managed encryptor por defecto. Asumí afectación hasta confirmar lo contrario.

Quiénes están afectados

La vulnerabilidad es multi-plataforma. A diferencia de los Patch Tuesday tradicionales de Microsoft que suelen enfocarse en Windows, este afecta a cualquier instancia de ASP.NET Core 10.x desplegada sobre Windows, Linux o macOS. Si tenés apps en Azure App Service, en contenedores Linux, en Kubernetes, en Docker Swarm o en VMs Linux desplegando una versión afectada, estás en el alcance. La recomendación del proyecto Duende IdentityServer confirma el carácter global: "CVE-2026-40372 is an Elevation of Privilege attack. It has a CVSS score of 9.1 (HIGH) due to the impact it can have".

Las aplicaciones más expuestas son aquellas que dependen de Data Protection para funcionalidad de seguridad crítica:

  • Apps con ASP.NET Core Identity: el framework de autenticación de referencia usa Data Protection para generar tokens de reset de contraseña, confirmación de email y two-factor.
  • Proyectos con Duende IdentityServer / OpenIddict: los servidores OAuth/OIDC construidos sobre .NET cifran tickets internos con Data Protection.
  • Blazor Server: el circuit reconnection token que mantiene la conexión entre navegador y servidor usa Data Protection.
  • SignalR con autenticación: los handshakes autenticados cifran información de sesión.
  • Cualquier app con cookies de auth: el cookie ticket que guarda el estado del usuario está protegido por Data Protection.
  • APIs con antiforgery tokens: el CSRF protection de MVC/Razor Pages depende de la integridad de estos tokens.

Cómo verificar si tu aplicación es vulnerable

La forma más directa es inspeccionar la versión del paquete Microsoft.AspNetCore.DataProtection que tu aplicación tiene resuelto. Si es entre 10.0.0 y 10.0.6 inclusive, estás afectado. El fix está en 10.0.7.

# Verificar versión instalada en un proyecto
dotnet list package --include-transitive | grep -i "dataprotection"

# O inspeccionar el csproj + lockfile
grep -r "DataProtection" *.csproj packages.lock.json 2>/dev/null

# En un entorno de producción Linux
find / -name "Microsoft.AspNetCore.DataProtection.dll" 2>/dev/null \
  -exec sh -c 'echo "==" ; echo "{}" ; sigtool --print-version "{}" 2>/dev/null || strings "{}" | grep -E "^10\.0\.[0-9]+"' \;

# Actualizar todos los proyectos de una solución
dotnet add package Microsoft.AspNetCore.DataProtection --version 10.0.7

# Verificar el .NET runtime instalado en el server
dotnet --list-runtimes | grep "Microsoft.AspNetCore.App"
Enter fullscreen mode Exit fullscreen mode

Si tu aplicación corre con el runtime ASP.NET Core bundle (instalado en el servidor), actualizar el runtime a la versión patcheada cubre el fix sin necesidad de rebuildear la app. Si tu aplicación es self-contained (trae sus propios assemblies), tenés que rebuildear y redeplear. Para entornos Kubernetes con imágenes basadas en mcr.microsoft.com/dotnet/aspnet:10.0, rebuildear la imagen base pulleará la versión corregida.

Impacto: por qué un bug en DataProtection es peor que un CVE típico

Los CVE de elevation of privilege son comunes en Patch Tuesday; lo que hace especial a este es la ubicuidad del código afectado y el rol que ocupa en la cadena de confianza. Data Protection es usada por casi cualquier aplicación ASP.NET Core en producción, y cuando la primitiva que garantiza integridad criptográfica falla, cada pieza construida encima de ella hereda el fallo. Un atacante que explote CVE-2026-40372 no necesita comprometer tu base de datos, ni tu código, ni tus credenciales: le basta entender cómo construir el payload que el servidor va a aceptar como válido por sí mismo.

La analogía útil: es como si el sistema de firmas digitales de un banco estuviera firmando documentos sin leer qué dicen, y luego aceptara cualquier documento con una firma —no necesariamente la correcta— como legítimo. La apariencia externa del sistema (los tickets llevan un tag, la validación ocurre) permanece intacta. Lo que cambia es que el tag no cubre lo que debería cubrir.

A esto se suma un segundo factor: las versiones 10.x de ASP.NET Core son relativamente recientes, pero muchas organizaciones migraron rápido por las mejoras de rendimiento y de tooling que trae el stack. El universo de sistemas potencialmente vulnerables no es pequeño, y dado que el bug es un error lógico en verificación criptográfica, los proofs-of-concept pueden aparecer públicamente en días u horas.

Los bugs en criptografía autenticada no generan logs de error: los payloads forjados se aceptan silenciosamente como legítimos.

Mitigación: pasos concretos

El orden de acción recomendado para equipos que despliegan ASP.NET Core:

  • Inventariar versiones: generá una lista de todas las apps que corren ASP.NET Core 10.x en producción. Revisá tanto las versiones del runtime como las versiones de los paquetes NuGet transitivos.
  • Actualizar a 10.0.7 o superior: dotnet add package Microsoft.AspNetCore.DataProtection --version 10.0.7 en cada proyecto, rebuildear, testear en staging y redeployar. Para runtime compartido, actualizar el bundle ASP.NET Core en cada servidor.
  • Rotar llaves de Data Protection: aunque la vulnerabilidad no expone las llaves, invalidar las llaves existentes reduce la ventana de validez de cualquier payload forjado que ya esté circulando. La operación se hace vía IDataProtectionProvider programáticamente o rotando el key ring en el storage configurado.
  • Invalidar sesiones activas: si tu app usa cookies de sesión con larga duración, considerá forzar logout global para que los usuarios re-autentiquen con el nuevo key ring.
  • Revisar logs de auth: buscá patrones anómalos en logs recientes: usuarios apareciendo desde IPs inusuales, sesiones que aparecen sin login previo, elevación de privilegios inexplicable.
  • Actualizar Duende IdentityServer / OpenIddict: si usás estos proyectos encima de ASP.NET Core, consultá sus advisory propios para versiones compatibles con 10.0.7.
  • Pinear la versión parcheada: documentá en vuestro Directory.Packages.props o equivalente que la versión mínima de Microsoft.AspNetCore.DataProtection es 10.0.7, para evitar que un downgrade accidental reintroduzca el bug.

💭 Clave: actualizar el paquete sin rotar las llaves mitiga el bug pero no invalida payloads ya forjados que puedan estar en manos de un atacante. La rotación de llaves es el paso que cierra la ventana por completo.

Contexto: el patrón de regresiones en código criptográfico

CVE-2026-40372 se suma a una lista incómoda de bugs recientes en primitivas criptográficas de frameworks mainstream: la cuckoo filter en Redis 7.x que corrompía validación de membership (2024), la implementación incorrecta de Ed25519 en librerías de wallet cripto (2025), el downgrade silencioso de TLS 1.3 a 1.2 en ciertos stacks de Node.js (2025). El patrón es consistente: código que implementa primitivas bien especificadas pero que en el camino de optimización o de migración introduce una regresión sutil que solo se detecta cuando alguien mira con atención.

Para Microsoft, el caso particular del managed authenticated encryptor es doblemente incómodo: Data Protection es el subsistema que recomiendan explícitamente usar en lugar de criptografía manual, justamente porque maneja correctamente detalles como verificación HMAC constant-time, rotación de llaves y compatibilidad entre versiones. El hecho de que una regresión en ese subsistema permita elevation of privilege con CVSS 9.1 refuerza una lección incómoda: incluso las abstracciones "seguras por defecto" dependen de que la implementación actual esté escrita y testeada correctamente.

Preguntas frecuentes

¿Mi app en .NET Framework (no .NET Core) está afectada?

No. El CVE afecta específicamente a Microsoft.AspNetCore.DataProtection versiones 10.0.0 a 10.0.6 del ecosistema .NET moderno (ASP.NET Core). Las aplicaciones basadas en .NET Framework clásico usan un stack distinto y no están incluidas en el alcance.

Mi app usa ASP.NET Core 8.x. ¿Debo actualizar?

El advisory de Microsoft identifica específicamente versiones 10.0.0 a 10.0.6. Las versiones 8.x y 9.x no están listadas como afectadas. Sin embargo, revisá los release notes de tus versiones por cualquier backport si Microsoft decide publicar uno, y siempre mantené tu runtime en una versión con soporte activo.

¿Hay evidencia de explotación activa?

Al momento de la publicación del advisory, Microsoft no reportó explotación activa detectada. La vulnerabilidad fue descubierta durante la investigación interna de reportes de clientes sobre fallos de descifrado, no por telemetría de ataques. Eso no significa que no aparezcan exploits públicos pronto: un bug lógico en verificación HMAC es relativamente fácil de reproducir una vez que la descripción técnica está disponible.

¿Rotar las llaves va a romper las sesiones activas?

Sí. Cualquier payload cifrado con una llave rotada deja de ser válido, lo que invalida cookies de sesión, antiforgery tokens emitidos antes de la rotación, y cualquier dato cifrado con Data Protection. Los usuarios tendrán que re-autenticarse. En aplicaciones críticas, este es el comportamiento deseado; en aplicaciones menos sensibles, podés considerar ventanas de rotación gradual.

¿Puedo mitigar sin actualizar el paquete?

No hay workaround oficial documentado. El fix es el paquete actualizado. Cualquier mitigación alternativa (WAF rules, rate limiting, restricción de endpoints) reduce superficie de ataque pero no cierra la vulnerabilidad subyacente. Tratá el parche como obligatorio.

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

Top comments (0)