Skip to content

Commit 8bf8d44

Browse files
fix: prevent shell injection in staged file content reading
Replace execSync with string interpolation with spawnSync using an args array. File paths with shell metacharacters (quotes, semicolons, etc.) in their names are now passed safely without shell interpretation. Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
1 parent 1457c66 commit 8bf8d44

File tree

1 file changed

+17
-22
lines changed

1 file changed

+17
-22
lines changed

packages/react-doctor/src/utils/get-staged-files.ts

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,28 @@
1-
import { execSync } from "node:child_process";
1+
import { spawnSync } from "node:child_process";
22
import fs from "node:fs";
33
import path from "node:path";
44
import { GIT_SHOW_MAX_BUFFER_BYTES, SOURCE_FILE_PATTERN } from "../constants.js";
55

66
const getStagedFilePaths = (directory: string): string[] => {
7-
try {
8-
const output = execSync("git diff --cached --name-only --diff-filter=ACMR --relative", {
9-
cwd: directory,
10-
stdio: "pipe",
11-
})
12-
.toString()
13-
.trim();
14-
if (!output) return [];
15-
return output.split("\n").filter(Boolean);
16-
} catch {
17-
return [];
18-
}
7+
const result = spawnSync(
8+
"git",
9+
["diff", "--cached", "--name-only", "--diff-filter=ACMR", "--relative"],
10+
{ cwd: directory, stdio: "pipe", maxBuffer: GIT_SHOW_MAX_BUFFER_BYTES },
11+
);
12+
if (result.error || result.status !== 0) return [];
13+
const output = result.stdout.toString().trim();
14+
if (!output) return [];
15+
return output.split("\n").filter(Boolean);
1916
};
2017

2118
const readStagedContent = (directory: string, relativePath: string): string | null => {
22-
try {
23-
return execSync(`git show ":${relativePath}"`, {
24-
cwd: directory,
25-
stdio: "pipe",
26-
maxBuffer: GIT_SHOW_MAX_BUFFER_BYTES,
27-
}).toString();
28-
} catch {
29-
return null;
30-
}
19+
const result = spawnSync("git", ["show", `:${relativePath}`], {
20+
cwd: directory,
21+
stdio: "pipe",
22+
maxBuffer: GIT_SHOW_MAX_BUFFER_BYTES,
23+
});
24+
if (result.error || result.status !== 0) return null;
25+
return result.stdout.toString();
3126
};
3227

3328
interface StagedSnapshot {

0 commit comments

Comments
 (0)