

























@@ -167,20 +167,16 @@ function expectShellPayloadApprovalDenied(params: {
167167if (process.platform === "win32") {
168168return;
169169}
170-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), params.tmpPrefix));
171-try {
172-const scriptPath = path.join(tmp, params.fileName);
173-fs.writeFileSync(scriptPath, params.body);
174-fs.chmodSync(scriptPath, 0o755);
175-const prepared = buildSystemRunApprovalPlan({
176-command: ["/bin/sh", "-lc", scriptPath],
177-rawCommand: scriptPath,
178-cwd: tmp,
179-});
180-expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
181-} finally {
182-fs.rmSync(tmp, { recursive: true, force: true });
183-}
170+const tmp = createFixtureDir(params.tmpPrefix);
171+const scriptPath = path.join(tmp, params.fileName);
172+fs.writeFileSync(scriptPath, params.body);
173+fs.chmodSync(scriptPath, 0o755);
174+const prepared = buildSystemRunApprovalPlan({
175+command: ["/bin/sh", "-lc", scriptPath],
176+rawCommand: scriptPath,
177+cwd: tmp,
178+});
179+expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
184180}
185181186182function expectMutableFileOperandApprovalPlan(fixture: ScriptOperandFixture, cwd: string) {
@@ -478,7 +474,7 @@ describe("hardenApprovedExecutionPaths", () => {
478474];
479475480476it.runIf(process.platform !== "win32").each(cases)("$name", (testCase) => {
481-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-approval-hardening-"));
477+const tmp = createFixtureDir("openclaw-approval-hardening-");
482478const oldPath = process.env.PATH;
483479let pathToken: PathTokenSetup | null = null;
484480if (testCase.withPathToken) {
@@ -534,7 +530,6 @@ describe("hardenApprovedExecutionPaths", () => {
534530process.env.PATH = oldPath;
535531}
536532}
537-fs.rmSync(tmp, { recursive: true, force: true });
538533}
539534});
540535@@ -847,49 +842,41 @@ describe("hardenApprovedExecutionPaths", () => {
847842if (process.platform === "win32") {
848843return;
849844}
850-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-relative-binary-binding-"));
851-try {
852-const binaryPath = resolveNativeBinaryFixturePath();
853-const relativeBinaryPath = path.join(tmp, "tool");
854-fs.copyFileSync(binaryPath, relativeBinaryPath);
855-fs.chmodSync(relativeBinaryPath, 0o755);
856-const prepared = buildSystemRunApprovalPlan({
857-command: ["/bin/sh", "-lc", "./tool"],
858-rawCommand: "./tool",
859-cwd: tmp,
860-});
861-expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
862-} finally {
863-fs.rmSync(tmp, { recursive: true, force: true });
864-}
845+const tmp = createFixtureDir("openclaw-shell-relative-binary-binding-");
846+const binaryPath = resolveNativeBinaryFixturePath();
847+const relativeBinaryPath = path.join(tmp, "tool");
848+fs.copyFileSync(binaryPath, relativeBinaryPath);
849+fs.chmodSync(relativeBinaryPath, 0o755);
850+const prepared = buildSystemRunApprovalPlan({
851+command: ["/bin/sh", "-lc", "./tool"],
852+rawCommand: "./tool",
853+cwd: tmp,
854+});
855+expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
865856});
866857867858it("keeps fail-closed behavior for writable absolute native-binary shell payloads", () => {
868859if (process.platform === "win32") {
869860return;
870861}
871-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-absolute-binary-binding-"));
872-try {
873-const binaryPath = resolveNativeBinaryFixturePath();
874-const copiedBinaryPath = path.join(tmp, "tool");
875-fs.copyFileSync(binaryPath, copiedBinaryPath);
876-fs.chmodSync(copiedBinaryPath, 0o755);
877-const prepared = buildSystemRunApprovalPlan({
878-command: ["/bin/sh", "-lc", copiedBinaryPath],
879-rawCommand: copiedBinaryPath,
880-cwd: tmp,
881-});
882-expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
883-} finally {
884-fs.rmSync(tmp, { recursive: true, force: true });
885-}
862+const tmp = createFixtureDir("openclaw-shell-absolute-binary-binding-");
863+const binaryPath = resolveNativeBinaryFixturePath();
864+const copiedBinaryPath = path.join(tmp, "tool");
865+fs.copyFileSync(binaryPath, copiedBinaryPath);
866+fs.chmodSync(copiedBinaryPath, 0o755);
867+const prepared = buildSystemRunApprovalPlan({
868+command: ["/bin/sh", "-lc", copiedBinaryPath],
869+rawCommand: copiedBinaryPath,
870+cwd: tmp,
871+});
872+expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
886873});
887874888875it("keeps fail-closed behavior for owner-controlled read-only absolute binaries", () => {
889876if (process.platform === "win32") {
890877return;
891878}
892-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-owned-readonly-binding-"));
879+const tmp = createFixtureDir("openclaw-shell-owned-readonly-binding-");
893880const binaryPath = path.join(tmp, "tool");
894881try {
895882fs.copyFileSync(resolveNativeBinaryFixturePath(), binaryPath);
@@ -903,15 +890,14 @@ describe("hardenApprovedExecutionPaths", () => {
903890expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
904891} finally {
905892fs.chmodSync(tmp, 0o755);
906-fs.rmSync(tmp, { recursive: true, force: true });
907893}
908894});
909895910896it("keeps fail-closed behavior for symlinked binaries with writable targets", () => {
911897if (process.platform === "win32") {
912898return;
913899}
914-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-symlink-binary-binding-"));
900+const tmp = createFixtureDir("openclaw-shell-symlink-binary-binding-");
915901const stableDir = path.join(tmp, "stable");
916902const mutableDir = path.join(tmp, "mutable");
917903try {
@@ -932,7 +918,6 @@ describe("hardenApprovedExecutionPaths", () => {
932918expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
933919} finally {
934920fs.chmodSync(stableDir, 0o755);
935-fs.rmSync(tmp, { recursive: true, force: true });
936921}
937922});
938923@@ -972,49 +957,41 @@ describe("hardenApprovedExecutionPaths", () => {
972957if (process.platform === "win32") {
973958return;
974959}
975-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-race-binding-"));
976-try {
977-const scriptPath = path.join(tmp, "run.sh");
978-fs.writeFileSync(scriptPath, "#!/bin/sh\necho SAFE\n");
979-fs.chmodSync(scriptPath, 0o755);
980-const realStatSync = fs.statSync;
981-let targetStatCalls = 0;
982-const statSyncSpy = vi.spyOn(fs, "statSync").mockImplementation((pathLike, options) => {
983-const targetPath = typeof pathLike === "string" ? pathLike : pathLike.toString();
984-if (targetPath === scriptPath) {
985-targetStatCalls += 1;
986-if (targetStatCalls === 2) {
987-return realStatSync(tmp, options);
988-}
960+const tmp = createFixtureDir("openclaw-shell-race-binding-");
961+const scriptPath = path.join(tmp, "run.sh");
962+fs.writeFileSync(scriptPath, "#!/bin/sh\necho SAFE\n");
963+fs.chmodSync(scriptPath, 0o755);
964+const realStatSync = fs.statSync;
965+let targetStatCalls = 0;
966+const statSyncSpy = vi.spyOn(fs, "statSync").mockImplementation((pathLike, options) => {
967+const targetPath = typeof pathLike === "string" ? pathLike : pathLike.toString();
968+if (targetPath === scriptPath) {
969+targetStatCalls += 1;
970+if (targetStatCalls === 2) {
971+return realStatSync(tmp, options);
989972}
990-return realStatSync(pathLike, options);
991-});
992-try {
993-const prepared = buildSystemRunApprovalPlan({
994-command: ["/bin/sh", "-lc", scriptPath],
995-rawCommand: scriptPath,
996-cwd: tmp,
997-});
998-expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
999-} finally {
1000-statSyncSpy.mockRestore();
1001973}
974+return realStatSync(pathLike, options);
975+});
976+try {
977+const prepared = buildSystemRunApprovalPlan({
978+command: ["/bin/sh", "-lc", scriptPath],
979+rawCommand: scriptPath,
980+cwd: tmp,
981+});
982+expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
1002983} finally {
1003-fs.rmSync(tmp, { recursive: true, force: true });
984+statSyncSpy.mockRestore();
1004985}
1005986});
10069871007988it.each(unsafeRuntimeInvocationCases)("$name", (testCase) => {
1008989withFakeRuntimeBin({
1009990binName: testCase.binName,
1010991run: () => {
1011-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), testCase.tmpPrefix));
1012-try {
1013-testCase.setup?.(tmp);
1014-expectRuntimeApprovalDenied(testCase.command, tmp);
1015-} finally {
1016-fs.rmSync(tmp, { recursive: true, force: true });
1017-}
992+const tmp = createFixtureDir(testCase.tmpPrefix);
993+testCase.setup?.(tmp);
994+expectRuntimeApprovalDenied(testCase.command, tmp);
1018995},
1019996});
1020997});
@@ -1062,19 +1039,15 @@ describe("hardenApprovedExecutionPaths", () => {
10621039withFakeRuntimeBins({
10631040binNames: ["pnpm", "tsx"],
10641041run: () => {
1065-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-pnpm-dlx-shell-mode-"));
1066-try {
1067-fs.writeFileSync(path.join(tmp, "run.ts"), 'console.log("SAFE");\n');
1068-expect(
1069-resolveMutableFileOperandSnapshotSync({
1070-argv: ["pnpm", "dlx", "--shell-mode", "tsx ./run.ts"],
1071-cwd: tmp,
1072-shellCommand: null,
1073-}),
1074-).toEqual({ ok: true, snapshot: null });
1075-} finally {
1076-fs.rmSync(tmp, { recursive: true, force: true });
1077-}
1042+const tmp = createFixtureDir("openclaw-pnpm-dlx-shell-mode-");
1043+fs.writeFileSync(path.join(tmp, "run.ts"), 'console.log("SAFE");\n');
1044+expect(
1045+resolveMutableFileOperandSnapshotSync({
1046+argv: ["pnpm", "dlx", "--shell-mode", "tsx ./run.ts"],
1047+cwd: tmp,
1048+shellCommand: null,
1049+}),
1050+).toEqual({ ok: true, snapshot: null });
10781051},
10791052});
10801053});
@@ -1083,12 +1056,8 @@ describe("hardenApprovedExecutionPaths", () => {
10831056withFakeRuntimeBin({
10841057binName: "pnpm",
10851058run: () => {
1086-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-pnpm-dlx-package-bin-"));
1087-try {
1088-expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "hello"], tmp);
1089-} finally {
1090-fs.rmSync(tmp, { recursive: true, force: true });
1091-}
1059+const tmp = createFixtureDir("openclaw-pnpm-dlx-package-bin-");
1060+expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "hello"], tmp);
10921061},
10931062});
10941063});
@@ -1097,14 +1066,8 @@ describe("hardenApprovedExecutionPaths", () => {
10971066withFakeRuntimeBin({
10981067binName: "pnpm",
10991068run: () => {
1100-const tmp = fs.mkdtempSync(
1101-path.join(os.tmpdir(), "openclaw-pnpm-dlx-package-runtime-token-"),
1102-);
1103-try {
1104-expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "node"], tmp);
1105-} finally {
1106-fs.rmSync(tmp, { recursive: true, force: true });
1107-}
1069+const tmp = createFixtureDir("openclaw-pnpm-dlx-package-runtime-token-");
1070+expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "node"], tmp);
11081071},
11091072});
11101073});
@@ -1113,14 +1076,8 @@ describe("hardenApprovedExecutionPaths", () => {
11131076withFakeRuntimeBin({
11141077binName: "pnpm",
11151078run: () => {
1116-const tmp = fs.mkdtempSync(
1117-path.join(os.tmpdir(), "openclaw-pnpm-dlx-package-runtime-token-multi-"),
1118-);
1119-try {
1120-expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "node", "hello"], tmp);
1121-} finally {
1122-fs.rmSync(tmp, { recursive: true, force: true });
1123-}
1079+const tmp = createFixtureDir("openclaw-pnpm-dlx-package-runtime-token-multi-");
1080+expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "node", "hello"], tmp);
11241081},
11251082});
11261083});
@@ -1129,14 +1086,10 @@ describe("hardenApprovedExecutionPaths", () => {
11291086withFakeRuntimeBins({
11301087binNames: ["pnpm", "eslint"],
11311088run: () => {
1132-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-pnpm-dlx-package-file-"));
1133-try {
1134-fs.mkdirSync(path.join(tmp, "src"), { recursive: true });
1135-fs.writeFileSync(path.join(tmp, "src", "index.ts"), 'console.log("SAFE");\n');
1136-expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "eslint", "src/index.ts"], tmp);
1137-} finally {
1138-fs.rmSync(tmp, { recursive: true, force: true });
1139-}
1089+const tmp = createFixtureDir("openclaw-pnpm-dlx-package-file-");
1090+fs.mkdirSync(path.join(tmp, "src"), { recursive: true });
1091+fs.writeFileSync(path.join(tmp, "src", "index.ts"), 'console.log("SAFE");\n');
1092+expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "eslint", "src/index.ts"], tmp);
11401093},
11411094});
11421095});
@@ -1145,16 +1098,9 @@ describe("hardenApprovedExecutionPaths", () => {
11451098withFakeRuntimeBin({
11461099binName: "pnpm",
11471100run: () => {
1148-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-pnpm-dlx-package-data-tail-"));
1149-try {
1150-fs.writeFileSync(path.join(tmp, "run.ts"), 'console.log("SAFE");\n');
1151-expectApprovalPlanWithoutMutableOperand(
1152-["pnpm", "dlx", "cowsay", "tsx", "./run.ts"],
1153-tmp,
1154-);
1155-} finally {
1156-fs.rmSync(tmp, { recursive: true, force: true });
1157-}
1101+const tmp = createFixtureDir("openclaw-pnpm-dlx-package-data-tail-");
1102+fs.writeFileSync(path.join(tmp, "run.ts"), 'console.log("SAFE");\n');
1103+expectApprovalPlanWithoutMutableOperand(["pnpm", "dlx", "cowsay", "tsx", "./run.ts"], tmp);
11581104},
11591105});
11601106});
@@ -1183,26 +1129,22 @@ describe("hardenApprovedExecutionPaths", () => {
11831129});
1184113011851131it("captures the real shell script operand after value-taking shell flags", () => {
1186-const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shell-option-value-"));
1187-try {
1188-const scriptPath = path.join(tmp, "run.sh");
1189-fs.writeFileSync(scriptPath, "#!/bin/sh\necho SAFE\n");
1190-fs.writeFileSync(path.join(tmp, "errexit"), "decoy\n");
1191-const snapshot = resolveMutableFileOperandSnapshotSync({
1192-argv: ["/bin/bash", "-o", "errexit", "./run.sh"],
1193-cwd: tmp,
1194-shellCommand: null,
1195-});
1196-expect(snapshot).toEqual({
1197-ok: true,
1198-snapshot: {
1199-argvIndex: 3,
1200-path: fs.realpathSync(scriptPath),
1201-sha256: expect.any(String),
1202-},
1203-});
1204-} finally {
1205-fs.rmSync(tmp, { recursive: true, force: true });
1206-}
1132+const tmp = createFixtureDir("openclaw-shell-option-value-");
1133+const scriptPath = path.join(tmp, "run.sh");
1134+fs.writeFileSync(scriptPath, "#!/bin/sh\necho SAFE\n");
1135+fs.writeFileSync(path.join(tmp, "errexit"), "decoy\n");
1136+const snapshot = resolveMutableFileOperandSnapshotSync({
1137+argv: ["/bin/bash", "-o", "errexit", "./run.sh"],
1138+cwd: tmp,
1139+shellCommand: null,
1140+});
1141+expect(snapshot).toEqual({
1142+ok: true,
1143+snapshot: {
1144+argvIndex: 3,
1145+path: fs.realpathSync(scriptPath),
1146+sha256: expect.any(String),
1147+},
1148+});
12071149});
12081150});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。