From 71a3dd80e78a17dbb44136ab5499a1b855b2e4e8 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 23:55:07 +0000 Subject: [PATCH] fix: tighten safe bin runtime policy coverage --- .../exec-safe-bin-runtime-policy.test.ts | 22 +++++++++++++++---- src/infra/exec-safe-bin-runtime-policy.ts | 3 ++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/infra/exec-safe-bin-runtime-policy.test.ts b/src/infra/exec-safe-bin-runtime-policy.test.ts index af5510be5f2..8bc40b2d35a 100644 --- a/src/infra/exec-safe-bin-runtime-policy.test.ts +++ b/src/infra/exec-safe-bin-runtime-policy.test.ts @@ -13,8 +13,10 @@ describe("exec safe-bin runtime policy", () => { const interpreterCases: Array<{ bin: string; expected: boolean }> = [ { bin: "python3", expected: true }, { bin: "python3.12", expected: true }, + { bin: " C:\\Tools\\Python3.EXE ", expected: true }, { bin: "node", expected: true }, { bin: "node20", expected: true }, + { bin: "/usr/local/bin/node20", expected: true }, { bin: "ruby3.2", expected: true }, { bin: "bash", expected: true }, { bin: "busybox", expected: true }, @@ -30,10 +32,9 @@ describe("exec safe-bin runtime policy", () => { } it("lists interpreter-like bins from a mixed set", () => { - expect(listInterpreterLikeSafeBins(["jq", "python3", "myfilter", "node"])).toEqual([ - "node", - "python3", - ]); + expect( + listInterpreterLikeSafeBins(["jq", " C:\\Tools\\Python3.EXE ", "myfilter", "/usr/bin/node"]), + ).toEqual(["node", "python3"]); }); it("merges and normalizes safe-bin profile fixtures", () => { @@ -76,6 +77,19 @@ describe("exec safe-bin runtime policy", () => { expect(policy.unprofiledInterpreterSafeBins).toEqual(["python3"]); }); + it("prefers local safe bins over global ones when both are configured", () => { + const policy = resolveExecSafeBinRuntimePolicy({ + global: { + safeBins: ["python3", "jq"], + }, + local: { + safeBins: ["sort"], + }, + }); + + expect([...policy.safeBins]).toEqual(["sort"]); + }); + it("merges explicit safe-bin trusted dirs from global and local config", () => { const customDir = path.join(path.sep, "custom", "bin"); const agentDir = path.join(path.sep, "agent", "bin"); diff --git a/src/infra/exec-safe-bin-runtime-policy.ts b/src/infra/exec-safe-bin-runtime-policy.ts index 955d130de11..203f9d0761f 100644 --- a/src/infra/exec-safe-bin-runtime-policy.ts +++ b/src/infra/exec-safe-bin-runtime-policy.ts @@ -65,7 +65,8 @@ function normalizeSafeBinName(raw: string): string { return ""; } const tail = trimmed.split(/[\\/]/).at(-1); - return tail ?? trimmed; + const normalized = tail ?? trimmed; + return normalized.replace(/\.(?:exe|cmd|bat|com)$/i, ""); } export function isInterpreterLikeSafeBin(raw: string): boolean {