From 7f2596f71f1eecd27e3f5589201534d3358b904f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 30 Oct 2026 15:58:12 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL/H?= =?UTF-8?q?IGH]=20Fix=20command=20injection=20vulnerability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced unsafe `execSync` usage with array-based `spawnSync`. - Used `process.execPath` instead of a string `"node"`. - Handled non-zero exit status cleanly for `spawnSync`. - Added journal entry for command injection learning. Co-authored-by: connerkup <72580335+connerkup@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ packages/core/src/reconcile.ts | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..c6f87f2 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-10-30 - Command Injection in Syntax Checker +**Vulnerability:** Use of string-based \`execSync\` for node syntax checking (\`execSync(\\\`node --check "\${tempFile}"\\\`)\`) allows for potential command injection if \`tempFile\` path can be manipulated. +**Learning:** Even internal tool execution or paths that seem controlled should use array-based argument passing (e.g., \`spawnSync\`) and \`process.execPath\` to absolutely prevent injection vulnerabilities in execution engines. +**Prevention:** Always prefer \`spawnSync\` over \`execSync\`, use \`process.execPath\` for invoking node, and pass arguments as an array rather than constructing a command string. diff --git a/packages/core/src/reconcile.ts b/packages/core/src/reconcile.ts index b0285bc..482624f 100644 --- a/packages/core/src/reconcile.ts +++ b/packages/core/src/reconcile.ts @@ -1,4 +1,4 @@ -import { execSync } from "node:child_process"; +import { spawnSync } from "node:child_process"; import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; @@ -139,7 +139,13 @@ export function reconcile(options: ReconcileOptions): ReconcileResult { fs.writeFileSync(tempFile, extractedCode, "utf8"); try { - execSync(`node --check "${tempFile}"`, { stdio: "pipe" }); + const result = spawnSync(process.execPath, ["--check", tempFile], { stdio: "pipe" }); + if (result.error) throw result.error; + if (result.status !== 0) { + const err = new Error("Syntax check failed") as Error & { stderr: Buffer }; + err.stderr = result.stderr; + throw err; + } log.audit("Syntax check passed"); } catch (err) { const stderr =