# REPRO-2026-00110: Deno Command Injection via Incomplete Metacharacter Blocklist ## Summary Status: published Severity: high Type: security Confidence: Unknown ## Identifiers REPRO ID: REPRO-2026-00110 GHSA: GHSA-hmh4-3xvx-q5hr CVE: CVE-2026-27190 ## Package Name: deno Ecosystem: rust Affected: < 2.6.8 Fixed: 2.6.8 ## Root Cause # 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. ## Reproduction Details Reproduced: 2026-02-20T15:03:44.204Z Duration: 606 seconds Tool calls: 75 Turns: 50 Handoffs: 2 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00110 pruva-verify GHSA-hmh4-3xvx-q5hr pruva-verify CVE-2026-27190 Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00110&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00110/artifacts/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - GitHub Advisory: https://github.com/advisories/GHSA-hmh4-3xvx-q5hr - NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-27190 ## Artifacts - repro/rca_report.md (analysis, 4223 bytes) - repro/reproduction_steps.sh (reproduction_script, 2148 bytes) - bundle/source.json (other, 4035 bytes) - bundle/ticket.json (other, 6475 bytes) - bundle/ticket.md (ticket, 1808 bytes) - repro/poc.mjs (other, 1012 bytes) - logs/final_variant_test.log (log, 2945 bytes) - logs/result.txt (other, 13 bytes) - logs/run1.log (log, 460 bytes) - logs/run2.log (log, 460 bytes) - logs/variant_1_vuln.log (log, 54 bytes) - logs/variant_result.txt (other, 13 bytes) - logs/variant_test.log (log, 861 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00110 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00110/artifacts/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00110 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev