88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
buildSystemRunApprovalPlan,
|
|
hardenApprovedExecutionPaths,
|
|
} from "./invoke-system-run-plan.js";
|
|
|
|
describe("hardenApprovedExecutionPaths", () => {
|
|
it.runIf(process.platform !== "win32")(
|
|
"preserves shell-wrapper argv during approval hardening",
|
|
() => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-wrapper-"));
|
|
try {
|
|
const prepared = buildSystemRunApprovalPlan({
|
|
command: ["env", "sh", "-c", "echo SAFE"],
|
|
cwd: tmp,
|
|
});
|
|
expect(prepared.ok).toBe(true);
|
|
if (!prepared.ok) {
|
|
throw new Error("unreachable");
|
|
}
|
|
expect(prepared.plan.argv).toEqual(["env", "sh", "-c", "echo SAFE"]);
|
|
expect(prepared.cmdText).toBe("echo SAFE");
|
|
} finally {
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
}
|
|
},
|
|
);
|
|
|
|
it.runIf(process.platform !== "win32")(
|
|
"preserves dispatch-wrapper argv during approval hardening",
|
|
() => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-dispatch-wrapper-"));
|
|
try {
|
|
const hardened = hardenApprovedExecutionPaths({
|
|
approvedByAsk: true,
|
|
argv: ["env", "tr", "a", "b"],
|
|
shellCommand: null,
|
|
cwd: tmp,
|
|
});
|
|
expect(hardened.ok).toBe(true);
|
|
if (!hardened.ok) {
|
|
throw new Error("unreachable");
|
|
}
|
|
expect(hardened.argv).toEqual(["env", "tr", "a", "b"]);
|
|
} finally {
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
}
|
|
},
|
|
);
|
|
|
|
it.runIf(process.platform !== "win32")(
|
|
"pins direct PATH-token executable during approval hardening",
|
|
() => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-direct-pin-"));
|
|
const binDir = path.join(tmp, "bin");
|
|
fs.mkdirSync(binDir, { recursive: true });
|
|
const link = path.join(binDir, "poccmd");
|
|
fs.symlinkSync("/bin/echo", link);
|
|
const expected = fs.realpathSync(link);
|
|
const oldPath = process.env.PATH;
|
|
process.env.PATH = `${binDir}${path.delimiter}${oldPath ?? ""}`;
|
|
try {
|
|
const hardened = hardenApprovedExecutionPaths({
|
|
approvedByAsk: true,
|
|
argv: ["poccmd", "SAFE"],
|
|
shellCommand: null,
|
|
cwd: tmp,
|
|
});
|
|
expect(hardened.ok).toBe(true);
|
|
if (!hardened.ok) {
|
|
throw new Error("unreachable");
|
|
}
|
|
expect(hardened.argv).toEqual([expected, "SAFE"]);
|
|
} finally {
|
|
if (oldPath === undefined) {
|
|
delete process.env.PATH;
|
|
} else {
|
|
process.env.PATH = oldPath;
|
|
}
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
}
|
|
},
|
|
);
|
|
});
|