From 99525224b53e36aa269b4989bffc064c307c8b4f Mon Sep 17 00:00:00 2001 From: Semgrep Autofix Date: Wed, 25 Mar 2026 12:24:04 +0000 Subject: [PATCH] Fix command injection vulnerability in git checkout function Fix command injection vulnerability in `src/util/git.js` by replacing `exec` with `execFile`. ## Changes - Replace `exec` with `execFile` in the `checkout` function - Pass git command arguments as array elements instead of string interpolation - Run each git command sequentially with proper error handling ## Why The `exec` function spawns a shell to execute commands, which means shell metacharacters in user-controlled input (like the `hash` parameter) could be interpreted and executed. By using `execFile`, arguments are passed directly to the executable without shell interpretation, preventing injection attacks even if malicious input like `; rm -rf /` or `$(command)` is provided. ## Semgrep Finding Details Untrusted input might be injected into a command executed by the application, which can lead to a command injection vulnerability. An attacker can execute arbitrary commands, potentially gaining complete control of the system. To prevent this vulnerability, avoid executing OS commands with user input. If this is unavoidable, validate and sanitize the user input, and use safe methods for executing the commands. For more information, see [Command injection prevention for JavaScript ] (https://semgrep.dev/docs/cheat-sheets/javascript-command-injection/). @9071412 requested Semgrep Assistant generate this pull request to fix [a finding](https://semgrep.dev/orgs/bmbl/findings/283855440) from the detection rule [javascript.express.express-child-process.express-child-process](https://semgrep.dev/r/javascript.express.express-child-process.express-child-process). --- src/util/git.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/util/git.js b/src/util/git.js index 1d60938..1c169b5 100644 --- a/src/util/git.js +++ b/src/util/git.js @@ -1,5 +1,5 @@ const spawn = require('child_process').spawn; -const exec = require('child_process').exec; +const execFile = require('child_process').execFile; function clone(cwd, done) { const proc = spawn('git', ['clone', '--progress', process.env.REPO, 'repo'], { @@ -9,9 +9,20 @@ function clone(cwd, done) { } function checkout(cwd, hash, done) { - const cmd = `git checkout ${process.env.REPO_BRANCH} && git pull origin ${process.env.REPO_BRANCH} && git checkout ${hash}`; - exec(cmd, { cwd }, (err, stdout) => { - done(err, stdout); + const branch = process.env.REPO_BRANCH; + + execFile('git', ['checkout', branch], { cwd }, (err1) => { + if (err1) { + return done(err1, null); + } + execFile('git', ['pull', 'origin', branch], { cwd }, (err2) => { + if (err2) { + return done(err2, null); + } + execFile('git', ['checkout', hash], { cwd }, (err3, stdout) => { + done(err3, stdout); + }); + }); }); }