What's the vulnerability?

A command injection vulnerability exists in Deno's node:child_process implementation.

Root Cause Analysis

# Root Cause Analysis: GHSA-hmh4-3xvx-q5hr

## Summary

A command injection vulnerability exists in Deno's `node:child_process` implementation (specifically in the `spawnSync` and `spawn` functions). When using `shell: true` option with arguments passed as an array, the arguments were not properly escaped before being joined into a shell command string. This allowed shell metacharacters (particularly newlines `\n` and carriage returns `\r`) embedded in argument values to be interpreted by the shell as command separators, enabling arbitrary command execution.

## Impact

- **Package:** deno (Rust-based JavaScript/TypeScript runtime)
- **Affected Component:** `node:child_process` polyfill (ext/node/polyfills/internal/child_process.ts)
- **Affected Versions:** < 2.6.8
- **Patched Version:** 2.6.8
- **Severity:** HIGH (CVSS 8.1)
- **Consequences:** Arbitrary code execution when user-controlled input is passed to spawn functions with `shell: true`

## Root Cause

The vulnerability stems from improper argument escaping in the `normalizeSpawnArguments` function:

1. **Before the fix (v2.6.7 and earlier):**
   ```typescript
   if (options.shell) {
     let command = ArrayPrototypeJoin([file, ...args], " ");
     // ...
   }
   ```
   Arguments were simply joined with spaces, making no attempt to escape shell metacharacters.

2. **The fix (commit 9132ad958c83a0d0b199de12b69b877f63edab4c):**
   - Added `escapeShellArg()` function that properly escapes shell arguments
   - On Unix: wraps arguments in single quotes and escapes embedded single quotes
   - On Windows: wraps in double quotes and escapes embedded double quotes and backslashes
   - Arguments are now escaped before being joined into the shell command

3. **Additional fix:** The shell metacharacter check in `transformDenoShellCommand` was expanded from:
   ```regex
   /[();&|<>`!]/
   ```
   to:
   ```regex
   /[();&|<>`!\n\r]/
   ```
   This catches newline (`\n`) and carriage return (`\r`) characters used for command injection.

## Reproduction Steps

1. Execute `repro/reproduction_steps.sh` which:
   - Downloads Deno v2.6.7 (vulnerable version)
   - Creates a PoC that uses `spawnSync` with `shell: true` and a malicious argument containing a newline
   - The malicious argument: `/tmp/legitimate.ts\ntouch /tmp/rce_proof`
   - When the shell interprets this, it executes: `deno run --allow-all /tmp/legitimate.ts` followed by `touch /tmp/rce_proof`

2. **Expected evidence:**
   - The file `/tmp/rce_proof` is created
   - Script outputs: "VULNERABILITY CONFIRMED: Command injection via newline in shell argument"
   - Exit code: 0

## Evidence

- **Log files:** `logs/run1.log`, `logs/run2.log`, `logs/result.txt`
- **Key excerpt from run1.log:**
  ```
  Exploit worked: true
  VULNERABILITY CONFIRMED: Command injection via newline in shell argument
  
  === RESULT: VULNERABILITY CONFIRMED ===
  The newline command injection vulnerability is present in this version.
  Evidence: /tmp/rce_proof file was created via shell injection.
  -rw-r--r-- 1 root root 0 Feb 20 14:46 /tmp/rce_proof
  ```
- **Environment:** Linux x86_64, Deno 2.6.7

## Recommendations / Next Steps

1. **Immediate action:** Upgrade to Deno v2.6.8 or later
2. **For developers:** 
   - Avoid using `shell: true` with user-controlled input when possible
   - If shell features are needed, validate and sanitize all arguments
   - Use `shell: false` (default) and pass arguments as arrays when shell interpretation is not required
3. **Testing recommendations:**
   - Add test cases for shell metacharacter injection: `\n`, `\r`, `;`, `|`, `&`, `$()`, backticks, etc.
   - Test both Unix and Windows platforms (different escaping requirements)

## Additional Notes

- **Idempotency confirmed:** The reproduction script was executed twice consecutively and confirmed the vulnerability both times.
- **Edge cases:** The vulnerability affects both synchronous (`spawnSync`) and asynchronous (`spawn`) variants of child_process functions.
- **Platform notes:** While this reproduction was tested on Linux, the same vulnerability exists on Windows with different shell metacharacter behaviors. The fix addresses both platforms with platform-specific escaping logic.
One Command

Verify with pruva-verify

Run the Pruva CLI to automatically fetch and execute the reproduction script.

pruva-verify REPRO-2026-00110
or pruva-verify GHSA-hmh4-3xvx-q5hr
or pruva-verify CVE-2026-27190
Install: curl -fsSL https://pruva.dev/install.sh | sh

Or Run Manually

1

Download the script

curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00110/artifacts/reproduction_steps.sh
2

Make executable

chmod +x reproduction_steps.sh
3

Run the script

./reproduction_steps.sh
Run in a VM, container, or disposable environment. This exploits a real vulnerability.

How Pruva Reproduced This

Watch the AI agent's step-by-step process.

Loading session...

Artifacts

No artifacts available