← Todos los artículos

Visual Studio 2026 18.10.3: convierte NU1903 en una actualización auditable

Un flujo para investigar NU1903 con NuGet Audit y el MCP integrado de Visual Studio 2026, revisar el diff y aprobar la actualización con evidencia humana.

30 de septiembre de 2026 · · 10 min de lectura
Ilustración abstracta de paquetes de software, alerta de vulnerabilidad, revisión de cambios y aprobación humana antes de actualizar

Una alerta NU1903 durante restore pide una decisión de ingeniería, no un clic en «actualizar». El código significa que NuGet encontró una vulnerabilidad conocida de severidad alta en un paquete del grafo. El siguiente paso debe dejar evidencia de qué paquete está afectado, qué versión lo incorpora, qué cambia el grafo y quién aprobó el cambio.

Visual Studio 2026 ayuda a acortar ese recorrido. El servidor MCP de NuGet puede analizar las dependencias y proponer actualizaciones desde Copilot Chat. Aun así, la recomendación solo es un punto de partida: no demuestra que la vulnerabilidad sea explotable en tu aplicación, que la versión nueva sea compatible ni que el resultado sea seguro para producción.

18.10.3 es el parche; NuGet Audit llegó en 18.10.0

Las notas de versión de Microsoft separan dos hechos que conviene no mezclar:

Versión Fecha publicada Qué significa para este flujo
18.10.0 8 de septiembre de 2026 Actualización de septiembre que documenta NuGet Audit, las fuentes de auditoría y el servidor MCP de NuGet integrado en Visual Studio 2026.
18.10.1 15 de septiembre de 2026 Servicing intermedio con correcciones del producto.
18.10.2 22 de septiembre de 2026 Servicing intermedio con correcciones del producto.
18.10.3 29 de septiembre de 2026 Parche que corrige un bloqueo al descargar un proyecto por un componente de diseñador obsoleto y otro bloqueo después de recargar el diseñador de Windows Forms de .NET Framework.

Por tanto, actualizar a 18.10.3 es una decisión razonable para recibir el servicing vigente consultado, pero no debes atribuirle a ese parche la introducción de NuGet Audit o del MCP. Tampoco es una actualización del runtime .NET ni sustituye la actualización del paquete vulnerable.

Primero fija qué está auditando NuGet

NuGet ejecuta la auditoría como parte de restore y compara el grafo del proyecto con información de vulnerabilidades servida por las fuentes de auditoría. Los códigos tienen significados distintos:

Código Significado Decisión inicial
NU1900 No se pudo obtener la información de vulnerabilidades. Investigar conectividad, autenticación o disponibilidad de la fuente; no interpretar el fallo como «sin vulnerabilidades».
NU1901 Vulnerabilidad de severidad baja. Registrar y decidir según la política del repositorio.
NU1902 Vulnerabilidad de severidad moderada. Revisar exposición y una actualización compatible.
NU1903 Vulnerabilidad de severidad alta. Abrir revisión prioritaria; identificar la ruta directa o transitiva antes de cambiar versiones.
NU1904 Vulnerabilidad de severidad crítica. Pausar la entrega según la política y tratar la remediación como urgente.
NU1905 Una fuente de auditoría no ofrece una base de vulnerabilidades. Corregir la fuente o la configuración; no asumir que el resultado es limpio.

La propiedad NuGetAuditMode puede limitarse a direct o abarcar all. Para proyectos que apunten a net10.0 o superior, la documentación actual indica que el valor predeterminado es all; en otros destinos es direct. Si una solución tiene varios destinos, confirma cómo queda el modo efectivo antes de comparar resultados.

NuGetAuditLevel establece la severidad mínima que se reporta: low, moderate, high o critical; low es el valor predeterminado documentado. Elevarlo a moderate, high o critical puede ocultar avisos de menor severidad en ese flujo, pero no remedia ningún paquete ni reduce su riesgo. Define el nivel de acuerdo con la política del repositorio y conserva una revisión que no pierda señales relevantes.

Configura auditSources sin convertirla en un feed de paquetes

Una fuente de auditoría entrega información de vulnerabilidades; no tiene por qué ser una fuente desde la que se descargan paquetes. Esta separación es útil cuando la organización usa un feed privado o un proxy que concentra los paquetes, pero necesita consultar la base de vulnerabilidades de NuGet.

En un nuget.config gestionado por el repositorio, un ejemplo mínimo y sin secretos es:

<configuration>
  <auditSources>
    <clear />
    <add key="nuget.org" value="https://data.nuget.org/v3/index.json" />
  </auditSources>
</configuration>

data.nuget.org es el índice V3 que solo ofrece datos de vulnerabilidades. También existe https://api.nuget.org/v3/index.json, que incluye los recursos completos de nuget.org. Elige el endpoint permitido por la política de red y documenta la decisión. No uses el protocolo V2 para una configuración nueva.

El bloque anterior no reemplaza a packageSources: el feed privado y sus reglas de resolución siguen definiéndose aparte. Si una fuente de auditoría privada requiere autenticación, utiliza el proveedor de credenciales y el almacén de secretos del runner; no pegues usuarios, contraseñas, tokens ni URLs con secretos en nuget.config, en una captura o en el prompt de Copilot. Antes de aprobar, verifica además que cada fuente declarada exponga el recurso VulnerabilityInfo esperado por NuGet.

Si auditSources no está definida, o se limpia sin añadir otra fuente, NuGet puede usar packageSources y suprimir NU1905. Eso describe una regla de configuración, no una garantía de que el feed contenga datos completos. Una fuente que responde correctamente y no incluye una vulnerabilidad recién publicada tampoco convierte el grafo en seguro por sí sola.

Del NU1903 a una propuesta que se pueda revisar

El flujo siguiente está pensado para una rama de cambio o un entorno de staging y resume pasos derivados de la documentación oficial. Adáptalo al SDK, al target framework y a la política de tu repositorio.

1. Conserva el estado que produjo la alerta

Registra el commit, el SDK y las fuentes efectivas antes de editar una versión. dotnet --info ayuda a identificar el SDK del entorno. Guarda la salida de restore y el identificador de la recomendación, pero elimina credenciales y otros datos sensibles de cualquier artefacto compartido.

Después, determina si el paquete es directo o transitivo. En .NET 10 SDK, incluido el flujo de Visual Studio 2026, usa la forma actual:

dotnet package list --vulnerable --include-transitive

En .NET 9 SDK o anteriores, la forma equivalente es:

dotnet list package --vulnerable --include-transitive

La salida es diagnóstica y depende de que las dependencias estén restauradas y de las fuentes de paquetes y auditoría efectivas; no sustituye la revisión del grafo ni una nueva restauración. Inspecciona el .csproj, Directory.Packages.props, los archivos de bloqueo si el repositorio los usa y la ruta que introduce el paquete. Para una dependencia transitiva, suele ser preferible actualizar primero el paquete directo más cercano que pueda arrastrar una versión corregida, en lugar de fijar un parche arbitrario sin conocer el contrato. Este artículo describe el procedimiento y no afirma que LBE Tech haya ejecutado el comando.

2. Habilita el MCP que ya está integrado en Visual Studio 2026

En Visual Studio 2026, abre GitHub Copilot Chat, inicia sesión y usa el icono de herramientas de la barra inferior. Busca el servidor nuget y habilítalo una vez. No necesitas instalar el servidor con dnx para este escenario integrado.

La ruta externa es distinta: la guía del servidor MCP describe la ejecución mediante dnx con .NET 10 SDK o posterior, por ejemplo para Visual Studio 2022, VS Code o un agente configurado fuera del Visual Studio 2026 integrado. No mezcles esa configuración con la del IDE ni copies un mcp.json externo solo porque el servidor aparezca en la documentación.

En una organización, revisa además la allowlist y las políticas de datos para servidores MCP. El servidor puede leer el proyecto y sus dependencias; habilitarlo no autoriza a compartir secretos ni elimina las reglas de revisión del repositorio.

3. Pide una propuesta acotada

El prompt documentado por Microsoft para iniciar el análisis es:

Fix my package vulnerabilities

Puedes formularlo en español, pero delimita el trabajo: solicita que identifique el paquete que dispara NU1903, proponga la primera versión compatible sin esa vulnerabilidad conocida y muestre qué archivos cambiaría. No empieces por «actualiza todos los paquetes» en una rama de producción: ese alcance puede introducir saltos mayores y hacer más difícil atribuir una regresión.

La respuesta del MCP es una propuesta. Copilot puede sugerir o editar versiones, pero no sustituye la lectura del aviso de seguridad, el changelog del paquete, la licencia, la compatibilidad del target framework ni la decisión del mantenedor.

4. Revisa el diff como una entrada de cambio

Antes de aceptar, comprueba:

  • que la versión propuesta corrige el aviso indicado y que no queda un NU1903 o NU1904 asociado a otra ruta;
  • que el cambio afecta al archivo esperado (.csproj, Directory.Packages.props o lockfile) y no introduce una fuente nueva sin aprobación;
  • que el grafo transitivo no cambia de forma inesperada, especialmente en serializadores, clientes HTTP, autenticación y paquetes que cargan código al iniciar;
  • que el salto de versión no cambia el target framework, el runtime, los analizadores o la licencia sin una decisión explícita;
  • que el changelog y el aviso de seguridad explican la corrección y las posibles migraciones;
  • que el diff no contiene tokens, rutas privadas, archivos generados irrelevantes ni modificaciones ajenas.

Si no existe una versión compatible, el paquete está abandonado, el cambio requiere una migración mayor o la alerta sigue apareciendo, detén el flujo. Documenta la exposición, la mitigación temporal y la fecha de revisión. NuGetAuditSuppress puede excluir un aviso concreto cuando un análisis demuestra que no aplica, pero la documentación lo presenta como último recurso: no debe utilizarse para convertir una vulnerabilidad incómoda en un build verde.

5. Vuelve a ejecutar las comprobaciones fuera de la conversación

Con el diff revisado, repite el restore usando el mismo archivo de configuración que usará CI:

dotnet restore --configfile ./nuget.config

Luego compila y ejecuta las pruebas que cubren el contrato afectado. El objetivo no es demostrar que «el agente acertó», sino obtener evidencia de que el cambio es reproducible y que la aplicación conserva su comportamiento esperado. Si el repositorio tiene lockfiles, verifica que el cambio sea intencional y estable.

Para una comprobación específica en CI, puedes mantener las auditorías visibles en los builds locales y convertir sus códigos en errores solo en un pipeline dedicado:

<PropertyGroup>
  <NuGetAuditCodes>NU1900;NU1901;NU1902;NU1903;NU1904;NU1905</NuGetAuditCodes>
  <WarningsAsErrors Condition="'$(AuditPipeline)' == 'true'">$(WarningsAsErrors);$(NuGetAuditCodes)</WarningsAsErrors>
  <WarningsNotAsErrors Condition="'$(AuditPipeline)' != 'true'">$(WarningsNotAsErrors);$(NuGetAuditCodes)</WarningsNotAsErrors>
</PropertyGroup>

El nombre AuditPipeline es solo una propiedad de ejemplo: debe coincidir con la que use tu pipeline. Si tu política ya usa TreatWarningsAsErrors, revisa cómo interactúa con WarningsNotAsErrors para no ocultar accidentalmente una vulnerabilidad.

Cuándo aprobar y cuándo pausar

La aprobación humana debería dejar cuatro piezas de evidencia: el aviso original y su fuente de auditoría; el diff de versiones y del grafo; el resultado de restore, compilación y pruebas; y un análisis posterior en CI con el mismo criterio de severidad. La ausencia de una alerta después del cambio significa que no se encontró una vulnerabilidad conocida en ese momento, no que el código sea benigno ni que la aplicación sea inmune a todas las explotaciones.

Pausa la revisión si la fuente devuelve NU1900 o NU1905, si el paquete corregido no es compatible, si se propone un salto mayor no planificado, si el grafo cambia sin explicación, si falla una prueba relevante o si Copilot no puede mostrar qué modificó. También pausa si la organización no ha aprobado el servidor MCP para ese repositorio o si el cambio expone datos que no debían salir del entorno.

El resultado deseable no es «Copilot arregló el paquete». Es una actualización pequeña, trazable y reproducible: una fuente de auditoría conocida, una propuesta acotada, un diff leído por una persona y una verificación independiente antes de integrar.

Fuentes primarias

Comentarios

Cargando…