fix(exec): harden safe-bin trust and add explicit trusted dirs

This commit is contained in:
Peter Steinberger
2026-02-22 22:42:29 +01:00
parent 08fb38f729
commit 64b273a71c
18 changed files with 123 additions and 55 deletions

View File

@@ -195,8 +195,8 @@ describe("exec approvals safe shell command builder", () => {
expect(res.ok).toBe(true);
// Preserve non-safeBins segment raw (glob stays unquoted)
expect(res.command).toContain("rg foo src/*.ts");
// SafeBins segment is fully quoted
expect(res.command).toContain("'head' '-n' '5'");
// SafeBins segment is fully quoted and pinned to its resolved absolute path.
expect(res.command).toMatch(/'[^']*\/head' '-n' '5'/);
});
});
@@ -936,6 +936,30 @@ describe("exec approvals safe bins", () => {
});
expect(allowed.allowlistSatisfied).toBe(true);
});
it("does not auto-trust PATH-shadowed safe bins without explicit trusted dirs", () => {
if (process.platform === "win32") {
return;
}
const tmp = makeTempDir();
const fakeDir = path.join(tmp, "fake-bin");
fs.mkdirSync(fakeDir, { recursive: true });
const fakeHead = path.join(fakeDir, "head");
fs.writeFileSync(fakeHead, "#!/bin/sh\nexit 0\n");
fs.chmodSync(fakeHead, 0o755);
const result = evaluateShellAllowlist({
command: "head -n 1",
allowlist: [],
safeBins: normalizeSafeBins(["head"]),
env: makePathEnv(fakeDir),
cwd: tmp,
});
expect(result.analysisOk).toBe(true);
expect(result.allowlistSatisfied).toBe(false);
expect(result.segmentSatisfiedBy).toEqual([null]);
expect(result.segments[0]?.resolution?.resolvedPath).toBe(fakeHead);
});
});
describe("exec approvals allowlist evaluation", () => {