Deno's node:child_process implementation provided an escapeShellArg() helper used when callers passed shell: true to spawn / spawnSync / exec and friends. On Windows, the helper failed to quote arguments that contained cmd.exe metacharacters such as &, |, <, >, ^, !, (, ), and did not neutralize % (which cmd.exe expands even inside double-quoted strings). An attacker who controlled any portion of an argument passed to such a call could inject arbitrary additional commands into the spawned cmd.exe invocation.
This was the Windows counterpart to CVE-2026-27190, which fixed the same class of bug in the Unix branch of escapeShellArg.
On Windows, child_process with shell: true ran the command via cmd.exe /d /s /c "<command line>". Deno assembled that command line by joining the program name and each argument through escapeShellArg().
The vulnerable check was:
// If no special characters, return as-is
if (!/[\s"\\]/.test(arg)) {
return arg;
}
The regex covered only whitespace, double-quote, and backslash. Any argument containing cmd.exe-significant characters but none of those three was returned unquoted and therefore interpreted by the shell. The most straightforward exploit chained commands with &:
import { spawnSync } from "node:child_process";
spawnSync("echo", ["test&calc.exe"], { shell: true, encoding: "utf-8" });
The reporter confirmed this launched calc.exe on Windows 11 with Deno 2.7.5. The same shape worked for |, <, >, ^, !, (, and ).
A secondary defect existed even when arguments were quoted: cmd.exe expands %FOO% environment-variable references inside double-quoted strings. Without either doubling % or rejecting it, an argument like "%USERPROFILE%" leaked environment data into the command line.
From the report, run on Windows with Deno < 2.7.10:
import { spawnSync } from "node:child_process";
const maliciousInput = "test&calc.exe";
const result = spawnSync("echo", [maliciousInput], {
shell: true,
encoding: "utf-8",
});
console.log(result);
Observed: calc.exe launched as a side effect of the echo call.
Any Deno program on Windows that called child_process.spawn / spawnSync / exec (or any shell helper that funneled through escapeShellArg) with shell: true and incorporated untrusted input into an argument was exposed to arbitrary command execution in the context of the Deno process. The CVSS vector treated this as network-reachable / high-complexity because the typical exposure path was a Deno service accepting external input and forwarding it to a shelled-out subprocess.
Not affected:
shell: true (the default), which executed the program directly via CreateProcess without cmd.exe interpretation.escapeShellArg and were already fixed under CVE-2026-27190.shell: true — those were the caller's responsibility and were never sanitized by Deno.Users on unpatched versions could mitigate by:
shell: true in node:child_process calls on Windows.cmd.exe metacharacters (& | < > ^ ! ( ) %) before passing them to spawn / spawnSync / exec.{
"sources": [
{
"imported": "2026-06-27T08:36:01.335Z",
"id": "CVE-2026-49402",
"database_specific": {
"status": "Analyzed"
},
"published": "2026-06-23T18:18:03.177Z",
"html_url": "https://nvd.nist.gov/vuln/detail/CVE-2026-49402",
"url": "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-49402",
"modified": "2026-06-26T17:33:10.807Z"
},
{
"url": "https://api.github.com/advisories/GHSA-7xh3-mhg9-jcw8",
"html_url": "https://github.com/advisories/GHSA-7xh3-mhg9-jcw8",
"id": "GHSA-7xh3-mhg9-jcw8",
"published": "2026-06-16T19:07:44Z",
"imported": "2026-06-27T08:36:14.212Z",
"modified": "2026-06-16T19:07:48Z"
},
{
"url": "https://euvdservices.enisa.europa.eu/api/enisaid?id=EUVD-2026-38546",
"html_url": "https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-38546",
"id": "EUVD-2026-38546",
"published": "2026-06-23T17:20:50Z",
"imported": "2026-06-27T08:36:01.407Z",
"modified": "2026-06-25T03:55:49Z"
}
],
"license": "CC-BY-4.0"
}