fix: reject Git diff driver helpers

This commit is contained in:
2026-08-10 00:30:06 +02:00
parent e042692cae
commit c10857405a
2 changed files with 40 additions and 5 deletions
+31
View File
@@ -317,6 +317,37 @@ test("raw runCommand rejects a configured clean filter before exact Git add", as
await assert.rejects(lstat(marker));
});
test("raw runCommand rejects a diff driver textconv before exact Git show", async () => {
const repositoryRoot = await fakeRepository();
const marker = join(repositoryRoot, "textconv-helper-ran");
const helper = join(repositoryRoot, "textconv-helper");
await execFileAsync("/usr/bin/git", ["init", "--initial-branch=main"], { cwd: repositoryRoot });
await execFileAsync("/usr/bin/git", ["config", "user.name", "P1 Fixture Curator"], { cwd: repositoryRoot });
await execFileAsync("/usr/bin/git", ["config", "user.email", "p1-curator@example.invalid"], { cwd: repositoryRoot });
await writeFile(join(repositoryRoot, ".gitattributes"), "file diff=evil\n");
await execFileAsync("/usr/bin/git", ["add", ".gitattributes"], { cwd: repositoryRoot });
await execFileAsync("/usr/bin/git", ["commit", "-m", "attributes"], { cwd: repositoryRoot });
await writeFile(join(repositoryRoot, "file"), "v1\n");
await execFileAsync("/usr/bin/git", ["add", "file"], { cwd: repositoryRoot });
await execFileAsync("/usr/bin/git", ["commit", "-m", "v1"], { cwd: repositoryRoot });
await writeFile(join(repositoryRoot, "file"), "v2\n");
await execFileAsync("/usr/bin/git", ["add", "file"], { cwd: repositoryRoot });
await execFileAsync("/usr/bin/git", ["commit", "-m", "v2"], { cwd: repositoryRoot });
await writeFile(helper, `#!/bin/sh\nprintf ran > '${marker}'\nexit 0\n`, { mode: 0o700 });
await execFileAsync("/usr/bin/git", ["config", "diff.evil.textconv", `'${helper}'`], { cwd: repositoryRoot });
const emptyHooks = join(repositoryRoot, "registry", "locks", "empty-hooks");
await mkdir(emptyHooks, { recursive: true });
const { gitPath } = await resolveProductionExecutables({
repositoryRoot: await realpath(join(dirname(fileURLToPath(import.meta.url)), "..", "..")),
});
await assert.rejects(
runCommand({ executable: gitPath, argv: ["-c", `core.hooksPath=${emptyHooks}`, "show", "HEAD"], cwd: repositoryRoot, env: process.env }),
/unsafe Git repository state/,
);
await assert.rejects(lstat(marker));
});
test("safe environment rejects ambient THT and keeps only strict process allowlist plus fixture values", () => {
const safe = buildSafeEnvironment({