Puntos clave
- CVE-2026-112948 en los servidores de desarrollo de Vitest 5 anuló las reglas predeterminadas server.fs.deny de Vite, exponiendo archivos .env y claves privadas mediante HTTP plano.
- Cualquier proceso o cliente de red local capaz de consultar el puerto de la UI/API de Vite podía extraer secretos internos y credenciales de acceso.
- Todas las credenciales presentes en el archivo .env durante sesiones activas de Vitest UI deben revocarse inmediatamente y rotarse mediante CSPRNG local.
Resumen Ejecutivo y Contexto de la Vulnerabilidad
El 21 de octubre de 2026, la base de datos de avisos de seguridad de GitHub publicó CVE-2026-112948 (GHSA-p458-7748-mcp3), exponiendo una configuración incorrecta crítica de acceso a archivos en los servidores de desarrollo de Vitest 5.
En configuraciones de desarrollo específicas (en particular al ejecutar la interfaz interactiva vitest --ui, el modo de navegador @vitest/browser o al habilitar el parámetro remoto api), el servidor HTTP subyacente de Vitest no aplicó las reglas predeterminadas server.fs.deny de Vite.
El resultado: activos confidenciales del proyecto que Vite normalmente protege de manera predeterminada (incluidos .env, .env.local, .npmrc, certificados SSL privados, metadatos de .git y el archivo de autenticación interno .vitest-secret-token) podían descargarse a través de HTTP sin autenticación por cualquier cliente de red o mediante pestañas de navegador maliciosas a través de peticiones cross-origin.

Causa Raíz Técnica: Por Qué se Anuló server.fs.deny
En una configuración estándar de Vite, server.fs.deny protege rutas confidenciales mediante patrones integrados:
// Patrones de denegación predeterminados de Vite:
['.env', '.env.*', '*.{crt,pem}', '**/.git/**', '**/.npmrc']Cuando Vitest 5 introdujo su servidor API interno y la autenticación por token en la interfaz (.vitest-secret-token), añadió su archivo de token a la lista de exclusión. Sin embargo, dos comportamientos del motor de Vite generaron una omisión silenciosa:
- Sobrescritura Prematura del Array: Vite solo inyecta su lista predeterminada de exclusión cuando
server.fs.denyes completamenteundefined. Cuando Vitest asignó un array que contenía únicamente['.vitest-secret-token'], las reglas estándar de Vite fueron descartadas en lugar de combinarse. - Precompilación del Matcher: Vite compila la lista
denyen una expresión regular interna durante la inicialización de la configuración. Las modificaciones dinámicas realizadas posteriormente en tiempo de ejecución no tuvieron efecto en la canalización activa de entrega de archivos HTTP.
Si ejecutó vitest --ui en una red local compartida o probó aplicaciones en navegadores con múltiples pestañas abiertas, cualquier script capaz de consultar localhost:51204 podía extraer sus credenciales privadas.
Flujo de Trabajo para la Mitigación y Rotación de Credenciales
1. Actualizar las Dependencias de Vitest
Los mantenedores de Vitest publicaron versiones corregidas que resuelven la compilación del filtro. Actualice las dependencias del proyecto de inmediato:
npm install -D vitest@latest @vitest/ui@latest @vitest/browser@latest
# o con pnpm:
pnpm update vitest @vitest/ui @vitest/browser2. Revocar y Reemitir Credenciales Filtradas
Considere comprometidos todos los secretos ubicados en archivos .env si Vitest UI estuvo activo en redes compartidas:
- Tokens de acceso a proveedores en la nube (AWS, GCP, Cloudflare)
- Credenciales de bases de datos (Postgres, Redis, cadenas de conexión MongoDB)
- Secretos de cliente OAuth 2.0 y claves de firma JWT
- Claves de API de terceros (Stripe, Resend, GitHub PATs)

3. Generar Secretos Criptográficos de Alta Entropía en el Cliente
Al generar credenciales de reemplazo, evite generadores en línea que registren entradas en registros de servidores. Utilice la Web Crypto API (crypto.getRandomValues) para generar números pseudoaleatorios criptográficamente seguros (CSPRNG):
function generateSecureToken(byteLength = 32): string {
const bytes = new Uint8Array(byteLength);
crypto.getRandomValues(bytes);
return Array.from(bytes)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}Para una rotación inmediata sin necesidad de programar código adicional:
- Genere claves de API de 256 bits, tokens hexadecimales y secretos Base32 conforme a RFC 4648 utilizando el Generador de Tokens de DevOmniTools.
- Inspeccione notificaciones, audiencia y caducidad de tokens rotados con el Decodificador JWT Offline de DevOmniTools.
Protección Defensiva Adicional
Refuerce vitest.config.ts o vite.config.ts con configuraciones explícitas de server.fs.strict y patrones de exclusión manuales:
import { defineConfig } from 'vitest/config';
export default defineConfig({
server: {
fs: {
strict: true,
deny: [
'**/.env*',
'**/*.pem',
'**/*.key',
'**/.git/**',
'**/.npmrc',
'**/.vitest-secret-token'
]
}
}
});FAQ
¿Cuál es la causa raíz principal de CVE-2026-112948 en Vitest 5?
Vitest agregó su archivo interno de token a server.fs.deny como una lista explícita, lo que provocó que Vite descartara sus patrones predeterminados en lugar de fusionarlos, permitiendo lecturas HTTP no autenticadas de archivos .env y claves privadas.
¿Se ven afectadas las ejecuciones de pruebas desde la línea de comandos?
No. Las ejecuciones headless (vitest run) no inician un servidor HTTP. La vulnerabilidad solo afecta ejecuciones con --ui, @vitest/browser o la opción api: true habilitada.
¿Cómo se deben rotar de forma segura los tokens .env filtrados?
Revoque de inmediato las claves en los paneles de control de la nube y bases de datos, y genere nuevos tokens criptográficamente seguros de 256 bits mediante CSPRNG en herramientas del lado del cliente sin transmitir credenciales por la red.