flawopen.com/Teardowns/cve-2024-27980-nodejs-windows-batch-injection
CVE-2024-27980: Node.js en Windows
En Windows, spawn() y spawnSync() podían permitir inyección de comandos al ejecutar archivos batch, incluso sin la opción shell.
Imagina que un programa entrega argumentos a un archivo batch, pero Windows necesita un intérprete de comandos para ejecutarlo. Ese intérprete puede leer los argumentos como sintaxis de comando. Node.js corrigió el problema rechazando la ejecución directa de archivos batch, en lugar de intentar adivinar cómo escapar cada argumento.
Conceptos Clave y Términos
child_process.spawn()- API asíncrona de Node.js para iniciar un proceso con un ejecutable y una lista de argumentos.
Archivo batch- Archivo .bat o .cmd interpretado por el shell de Windows, no un ejecutable ordinario con parsing universal de argv.
Metacarácter de shell- Carácter cuyo significado depende del intérprete de comandos y puede cambiar la estructura del comando.
EINVAL- Código de error con el que Node.js rechaza la ejecución directa insegura de archivos batch.
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-77
Análisis de Causa Raíz
En Windows, los archivos .bat y .cmd los interpreta un shell; no siempre es posible escapar los argumentos de forma inequívoca. El aviso de Node.js indica que argumentos maliciosos podían inyectar comandos mediante child_process.spawn() y spawnSync() incluso sin habilitar shell. El parche upstream detecta nombres que terminan en .bat o .cmd, sin distinguir mayúsculas, y devuelve EINVAL antes de llamar a uv_spawn(). La corrección no implementa sanitizeBatchArg() ni demuestra que shell: true sea seguro. Un aviso posterior identificó una corrección incompleta para otras extensiones de archivos batch (CVE-2024-36138); usa una versión actualizada que incluya ese segundo parche.
Flujo de Ataque Paso a Paso
La aplicación llama a la API de procesos
En Windows, la aplicación usa child_process.spawn() o spawnSync() para iniciar un archivo .bat o .cmd con argumentos que pueden incluir datos externos.
El destino es un archivo batch
La ejecución de archivos batch implica reglas de shell; una lista de argumentos no evita por sí sola la interpretación de metacaracteres.
Windows interpreta los argumentos
El comportamiento vulnerable podía hacer que un argumento se interpretase como sintaxis de comando incluso con shell: false.
Node.js bloquea la ejecución directa
El parche devuelve EINVAL al ejecutar directamente .bat/.cmd. CVE-2024-36138 reveló una brecha residual en otras extensiones; instala versiones que incluyan ambas correcciones.
Código Fuente: Vulnerable vs. Seguro
// Fragmento de src/process_wrap.cc anterior al parche de seguridad
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// El nombre del archivo se pasaba a uv_spawn() sin rechazar archivos por lotes.
// Fragmento del parche upstream de CVE-2024-27980
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// No siempre es posible escapar argumentos de archivos por lotes sin ambigüedad.
if (IsWindowsBatchFile(options.file))
err = UV_EINVAL;
if (err == 0) {
err = uv_spawn(env->event_loop(), &wrap->process_, &options);
wrap->MarkAsInitialized();
}
Lista de Verificación de Seguridad para Ingeniería
- ✓Actualiza a una versión de Node.js con soporte que incluya los parches de
CVE-2024-27980yCVE-2024-36138. - ✓Evita ejecutar scripts batch con datos externos; prefiere un ejecutable directo con argumentos validados.
- ✓Si el shell es inevitable, trata shell: true como ejecución de comandos y aplica validación estricta y controles de autorización.
- ✓Añade pruebas en Windows para
spawn()yspawnSync()con extensiones batch y verifica el rechazo seguro con EINVAL.