FlawOpen

flawopen.com/Teardowns/cve-2024-27980-nodejs-windows-batch-injection

● CVE-2024-27980 · CVSS 8.1 · Alta
Investigación · FlawOpen

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.

💡 Explicación en Lenguaje Sencillo (ELI5)

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

Paso 1

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.

Paso 2

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.

Paso 3

Windows interpreta los argumentos

El comportamiento vulnerable podía hacer que un argumento se interpretase como sintaxis de comando incluso con shell: false.

Paso 4

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

IMPLEMENTACIÓN VULNERABLE
// 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.
PARCHE SEGURO Y ROBUSTO
// 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

Fuentes