From f7d992c830c5f2ec5749852e66c0195e3ed7fe30 Mon Sep 17 00:00:00 2001 From: chenyc-hust Date: Thu, 5 Mar 2026 09:42:23 +0800 Subject: [PATCH] fix: prevent command injection in git-changes-commit-message tool Replace child_process.exec with execFile to avoid shell interpretation. The previous implementation executed `cd ${cwd}` and git commands using child_process.exec, which allows shell metacharacters in user-controlled input (autoCommitPath) to be interpreted by the shell. This change: - removes the unsafe `cd ${cwd}` shell call - replaces exec with execFile - executes git commands using argument arrays This prevents command injection while preserving the original functionality. --- index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.ts b/index.ts index 86ad90a..5d11e48 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; -import { exec } from 'child_process'; +import { execFile } from "child_process"; import { promisify } from 'util'; import OpenAI from 'openai'; import * as dotenv from 'dotenv'; @@ -22,7 +22,7 @@ if (!apiKey) { dotenv.config(); -const execAsync = promisify(exec); +const execFileAsync = promisify(execFile); // Initialize OpenAI client const openai = new OpenAI({ @@ -41,9 +41,9 @@ async function getGitChanges(input: string) { // Get staged and unstaged changes const cwd = input || process.cwd(); console.log("cwd", cwd); - await execAsync(`cd ${cwd}`); - const { stdout: diffOutput } = await execAsync('git diff HEAD', { cwd }); - const { stdout: statusOutput } = await execAsync('git status --porcelain', { cwd }); + + const { stdout: diffOutput } = await execFileAsync("git", ["diff", "HEAD"], { cwd }); + const { stdout: statusOutput } = await execFileAsync("git", ["status", "--porcelain"], { cwd }); // Process the changes const changes = {