Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2023-10-25 - [Command Injection Risk]
**Vulnerability:** Use of `execSync` with a string interpolated path in `reconcile.ts` (`execSync(\`node --check "\${tempFile}"\`)`) opened up a command injection risk if the file path was ever attacker-controlled or contained quotes/shell metacharacters.
**Learning:** Even internal file paths (`path.join` with `options.workspace`) shouldn't be blindly trusted to shell execution (`execSync` or `spawn` with `shell: true`), as quotes or shell metacharacters could still technically cause escaping depending on OS path characteristics or upstream workspace configuration.
**Prevention:** Use `spawnSync` (or `spawn`) with an explicit argument array (`["--check", tempFile]`) and avoid shell execution. For Node scripts, invoke `process.execPath` explicitly instead of depending on `node` in the PATH string.
7 changes: 5 additions & 2 deletions packages/core/src/reconcile.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -139,7 +139,10 @@ export function reconcile(options: ReconcileOptions): ReconcileResult {
fs.writeFileSync(tempFile, extractedCode, "utf8");

try {
execSync(`node --check "${tempFile}"`, { stdio: "pipe" });
const checkResult = spawnSync(process.execPath, ["--check", tempFile], { stdio: "pipe", encoding: "utf8" });
if (checkResult.status !== 0) {
throw new Error(checkResult.stderr || checkResult.stdout || "Syntax check failed");
}
log.audit("Syntax check passed");
} catch (err) {
const stderr =
Expand Down
Loading