fix: handle Windows safe-bin exe names
This commit is contained in:
@@ -1908,6 +1908,7 @@ public struct ExecApprovalsSnapshot: Codable, Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct ExecApprovalRequestParams: Codable, Sendable {
|
public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||||
|
public let id: String?
|
||||||
public let command: String
|
public let command: String
|
||||||
public let cwd: String?
|
public let cwd: String?
|
||||||
public let host: String?
|
public let host: String?
|
||||||
@@ -1919,6 +1920,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
|||||||
public let timeoutms: Int?
|
public let timeoutms: Int?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
|
id: String?,
|
||||||
command: String,
|
command: String,
|
||||||
cwd: String?,
|
cwd: String?,
|
||||||
host: String?,
|
host: String?,
|
||||||
@@ -1929,6 +1931,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
|||||||
sessionkey: String?,
|
sessionkey: String?,
|
||||||
timeoutms: Int?
|
timeoutms: Int?
|
||||||
) {
|
) {
|
||||||
|
self.id = id
|
||||||
self.command = command
|
self.command = command
|
||||||
self.cwd = cwd
|
self.cwd = cwd
|
||||||
self.host = host
|
self.host = host
|
||||||
@@ -1940,6 +1943,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
|||||||
self.timeoutms = timeoutms
|
self.timeoutms = timeoutms
|
||||||
}
|
}
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
case command
|
case command
|
||||||
case cwd
|
case cwd
|
||||||
case host
|
case host
|
||||||
|
|||||||
@@ -1908,6 +1908,7 @@ public struct ExecApprovalsSnapshot: Codable, Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct ExecApprovalRequestParams: Codable, Sendable {
|
public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||||
|
public let id: String?
|
||||||
public let command: String
|
public let command: String
|
||||||
public let cwd: String?
|
public let cwd: String?
|
||||||
public let host: String?
|
public let host: String?
|
||||||
@@ -1919,6 +1920,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
|||||||
public let timeoutms: Int?
|
public let timeoutms: Int?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
|
id: String?,
|
||||||
command: String,
|
command: String,
|
||||||
cwd: String?,
|
cwd: String?,
|
||||||
host: String?,
|
host: String?,
|
||||||
@@ -1929,6 +1931,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
|||||||
sessionkey: String?,
|
sessionkey: String?,
|
||||||
timeoutms: Int?
|
timeoutms: Int?
|
||||||
) {
|
) {
|
||||||
|
self.id = id
|
||||||
self.command = command
|
self.command = command
|
||||||
self.cwd = cwd
|
self.cwd = cwd
|
||||||
self.host = host
|
self.host = host
|
||||||
@@ -1940,6 +1943,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
|||||||
self.timeoutms = timeoutms
|
self.timeoutms = timeoutms
|
||||||
}
|
}
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
case command
|
case command
|
||||||
case cwd
|
case cwd
|
||||||
case host
|
case host
|
||||||
|
|||||||
@@ -72,12 +72,13 @@ describe("exec approvals command resolution", () => {
|
|||||||
const dir = makeTempDir();
|
const dir = makeTempDir();
|
||||||
const binDir = path.join(dir, "bin");
|
const binDir = path.join(dir, "bin");
|
||||||
fs.mkdirSync(binDir, { recursive: true });
|
fs.mkdirSync(binDir, { recursive: true });
|
||||||
const exe = path.join(binDir, "rg");
|
const exeName = process.platform === "win32" ? "rg.exe" : "rg";
|
||||||
|
const exe = path.join(binDir, exeName);
|
||||||
fs.writeFileSync(exe, "");
|
fs.writeFileSync(exe, "");
|
||||||
fs.chmodSync(exe, 0o755);
|
fs.chmodSync(exe, 0o755);
|
||||||
const res = resolveCommandResolution("rg -n foo", undefined, { PATH: binDir });
|
const res = resolveCommandResolution("rg -n foo", undefined, { PATH: binDir });
|
||||||
expect(res?.resolvedPath).toBe(exe);
|
expect(res?.resolvedPath).toBe(exe);
|
||||||
expect(res?.executableName).toBe("rg");
|
expect(res?.executableName).toBe(exeName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves relative paths against cwd", () => {
|
it("resolves relative paths against cwd", () => {
|
||||||
@@ -127,7 +128,8 @@ describe("exec approvals safe bins", () => {
|
|||||||
const dir = makeTempDir();
|
const dir = makeTempDir();
|
||||||
const binDir = path.join(dir, "bin");
|
const binDir = path.join(dir, "bin");
|
||||||
fs.mkdirSync(binDir, { recursive: true });
|
fs.mkdirSync(binDir, { recursive: true });
|
||||||
const exe = path.join(binDir, "jq");
|
const exeName = process.platform === "win32" ? "jq.exe" : "jq";
|
||||||
|
const exe = path.join(binDir, exeName);
|
||||||
fs.writeFileSync(exe, "");
|
fs.writeFileSync(exe, "");
|
||||||
fs.chmodSync(exe, 0o755);
|
fs.chmodSync(exe, 0o755);
|
||||||
const res = analyzeShellCommand({
|
const res = analyzeShellCommand({
|
||||||
@@ -150,7 +152,8 @@ describe("exec approvals safe bins", () => {
|
|||||||
const dir = makeTempDir();
|
const dir = makeTempDir();
|
||||||
const binDir = path.join(dir, "bin");
|
const binDir = path.join(dir, "bin");
|
||||||
fs.mkdirSync(binDir, { recursive: true });
|
fs.mkdirSync(binDir, { recursive: true });
|
||||||
const exe = path.join(binDir, "jq");
|
const exeName = process.platform === "win32" ? "jq.exe" : "jq";
|
||||||
|
const exe = path.join(binDir, exeName);
|
||||||
fs.writeFileSync(exe, "");
|
fs.writeFileSync(exe, "");
|
||||||
fs.chmodSync(exe, 0o755);
|
fs.chmodSync(exe, 0o755);
|
||||||
const file = path.join(dir, "secret.json");
|
const file = path.join(dir, "secret.json");
|
||||||
|
|||||||
@@ -660,7 +660,11 @@ export function isSafeBinUsage(params: {
|
|||||||
if (params.safeBins.size === 0) return false;
|
if (params.safeBins.size === 0) return false;
|
||||||
const resolution = params.resolution;
|
const resolution = params.resolution;
|
||||||
const execName = resolution?.executableName?.toLowerCase();
|
const execName = resolution?.executableName?.toLowerCase();
|
||||||
if (!execName || !params.safeBins.has(execName)) return false;
|
if (!execName) return false;
|
||||||
|
const matchesSafeBin =
|
||||||
|
params.safeBins.has(execName) ||
|
||||||
|
(process.platform === "win32" && params.safeBins.has(path.parse(execName).name));
|
||||||
|
if (!matchesSafeBin) return false;
|
||||||
if (!resolution?.resolvedPath) return false;
|
if (!resolution?.resolvedPath) return false;
|
||||||
const cwd = params.cwd ?? process.cwd();
|
const cwd = params.cwd ?? process.cwd();
|
||||||
const exists = params.fileExists ?? defaultFileExists;
|
const exists = params.fileExists ?? defaultFileExists;
|
||||||
|
|||||||
Reference in New Issue
Block a user