flawopen.com/Teardowns/cve-2024-27980-nodejs-windows-batch-injection
CVE-2024-27980: Node.js Windows Command Injection
On Windows, spawn() and spawnSync() could allow command injection when launching batch files, even without the shell option.
Imagine a program handing arguments to a batch file, while Windows needs a command interpreter to run that file. The interpreter can read argument text as command syntax. Node.js fixed this by refusing direct batch-file launches instead of guessing a safe escape for every argument.
Core Concepts & Subsystem Terms
child_process.spawn()- Node.js asynchronous API that starts a process from an executable and an argument list.
Batch file- A .bat or .cmd file interpreted by the Windows shell, rather than a regular executable with universal argv parsing.
Shell metacharacter- A character whose meaning depends on the command interpreter and may change command structure.
EINVAL- The error code Node.js uses to reject unsafe direct batch-file spawning.
Framework mappings
- CWE reference for the weakness described in this guide: CWE-77
Root Cause Analysis
On Windows, .bat and .cmd files are interpreted by a command shell; their arguments cannot always be escaped unambiguously. Node.js reported that a malicious command-line argument could inject commands through child_process.spawn() and spawnSync() even when shell was not enabled. The upstream patch detects a .bat or .cmd suffix case-insensitively and returns EINVAL before uv_spawn(). It does not implement sanitizeBatchArg(), and it does not make shell: true safe. A later advisory identified an incomplete fix for other batch-file extensions (CVE-2024-36138); use an updated release that includes that follow-up fix.
Step-by-Step Attack Flow
Application calls the process API
On Windows, an application calls child_process.spawn() or spawnSync() to launch a .bat or .cmd file with arguments that may contain external data.
Target is a batch file
Batch files follow shell parsing rules; an argument array does not by itself prevent metacharacter interpretation.
Windows interprets the arguments
The vulnerable behavior could let an argument be interpreted as command syntax even when shell: false.
Node.js rejects direct spawning
The patch returns EINVAL for direct .bat/.cmd spawning. CVE-2024-36138 found a remaining gap for other extensions, so install a release containing both fixes.
Source Code: Flaw vs. Secure Implementation
// Excerpt from src/process_wrap.cc before the security patch
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// The filename was passed to uv_spawn() without rejecting batch files.
// Excerpt from the upstream CVE-2024-27980 patch
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// Batch arguments cannot always be escaped unambiguously.
if (IsWindowsBatchFile(options.file))
err = UV_EINVAL;
if (err == 0) {
err = uv_spawn(env->event_loop(), &wrap->process_, &options);
wrap->MarkAsInitialized();
}
Engineering & System Hardening Checklist
- ✓Upgrade to a supported Node.js release containing fixes for
CVE-2024-27980andCVE-2024-36138. - ✓Avoid launching batch scripts with external data; prefer a direct executable with validated arguments.
- ✓If a shell is unavoidable, treat shell: true as command execution and enforce strict validation and authorization.
- ✓Add Windows regression tests for
spawn(),spawnSync(), and batch extensions; verify unsafe direct launches fail with EINVAL.