From 60ed92d8419b5f2269f92529f45f5212a901d2c2 Mon Sep 17 00:00:00 2001 From: anupamme Date: Fri, 2 Oct 2026 11:03:23 +0000 Subject: [PATCH] fix: sanitize shell/subprocess call in repo-refresh.js The runFetch function executes git commands using execFile with the gitRoot parameter passed directly as a command-line argument Addresses CWE-78 --- src/repo-refresh.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/repo-refresh.js b/src/repo-refresh.js index ce44ac8..df42f42 100644 --- a/src/repo-refresh.js +++ b/src/repo-refresh.js @@ -111,8 +111,28 @@ function createRepoRefreshManager(opts = {}) { } // ── Fetch runner ───────────────────────────────────────── + // gitRoot must be an absolute, already-normalized path with no NUL bytes + // and no leading '-' (which git/execFile could otherwise mistake for an + // option). This is defense-in-depth on top of the known-gitRoots gate in + // repo-refresh-routes.js, in case this manager is ever wired to a less + // careful caller. + function isSafeGitRoot(p) { + return typeof p === 'string' && p.length > 0 && !p.includes('\0') + && path.isAbsolute(p) && path.normalize(p) === p + && !path.basename(p).startsWith('-'); + } + function runFetch(gitRoot) { return new Promise((resolve) => { + if (!isSafeGitRoot(gitRoot)) { + resolve(setState(gitRoot, { + status: 'error', + startedAt: null, + lastError: truncateErr('invalid gitRoot'), + lastErrorAt: Date.now(), + })); + return; + } let timeoutFired = false; let killTimer = null; let timeoutTimer = null;