mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 20:28:29 +00:00
fix(exec-approvals): coerce bare string allowlist entries to objects (#9790)
This commit is contained in:
committed by
George Pickett
parent
b0befb5f5d
commit
6ff209e932
@@ -11,12 +11,14 @@ import {
|
||||
matchAllowlist,
|
||||
maxAsk,
|
||||
minSecurity,
|
||||
normalizeExecApprovals,
|
||||
normalizeSafeBins,
|
||||
requiresExecApproval,
|
||||
resolveCommandResolution,
|
||||
resolveExecApprovals,
|
||||
resolveExecApprovalsFromFile,
|
||||
type ExecAllowlistEntry,
|
||||
type ExecApprovalsFile,
|
||||
} from "./exec-approvals.js";
|
||||
|
||||
function makePathEnv(binDir: string): NodeJS.ProcessEnv {
|
||||
@@ -584,3 +586,98 @@ describe("exec approvals default agent migration", () => {
|
||||
expect(resolved.file.agents?.default).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("normalizeExecApprovals handles string allowlist entries (#9790)", () => {
|
||||
it("converts bare string entries to proper ExecAllowlistEntry objects", () => {
|
||||
// Simulates a corrupted or legacy config where allowlist contains plain
|
||||
// strings (e.g. ["ls", "cat"]) instead of { pattern: "..." } objects.
|
||||
const file = {
|
||||
version: 1,
|
||||
agents: {
|
||||
main: {
|
||||
mode: "allowlist",
|
||||
allowlist: ["things", "remindctl", "memo", "which", "ls", "cat", "echo"],
|
||||
},
|
||||
},
|
||||
} as unknown as ExecApprovalsFile;
|
||||
|
||||
const normalized = normalizeExecApprovals(file);
|
||||
const entries = normalized.agents?.main?.allowlist ?? [];
|
||||
|
||||
// Each entry must be a proper object with a pattern string, not a
|
||||
// spread-string like {"0":"t","1":"h","2":"i",...}
|
||||
for (const entry of entries) {
|
||||
expect(entry).toHaveProperty("pattern");
|
||||
expect(typeof entry.pattern).toBe("string");
|
||||
expect(entry.pattern.length).toBeGreaterThan(0);
|
||||
// Spread-string corruption would create numeric keys — ensure none exist
|
||||
expect(entry).not.toHaveProperty("0");
|
||||
}
|
||||
|
||||
expect(entries.map((e) => e.pattern)).toEqual([
|
||||
"things",
|
||||
"remindctl",
|
||||
"memo",
|
||||
"which",
|
||||
"ls",
|
||||
"cat",
|
||||
"echo",
|
||||
]);
|
||||
});
|
||||
|
||||
it("preserves proper ExecAllowlistEntry objects unchanged", () => {
|
||||
const file: ExecApprovalsFile = {
|
||||
version: 1,
|
||||
agents: {
|
||||
main: {
|
||||
allowlist: [{ pattern: "/usr/bin/ls" }, { pattern: "/usr/bin/cat", id: "existing-id" }],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const normalized = normalizeExecApprovals(file);
|
||||
const entries = normalized.agents?.main?.allowlist ?? [];
|
||||
|
||||
expect(entries).toHaveLength(2);
|
||||
expect(entries[0]?.pattern).toBe("/usr/bin/ls");
|
||||
expect(entries[1]?.pattern).toBe("/usr/bin/cat");
|
||||
expect(entries[1]?.id).toBe("existing-id");
|
||||
});
|
||||
|
||||
it("handles mixed string and object entries in the same allowlist", () => {
|
||||
const file = {
|
||||
version: 1,
|
||||
agents: {
|
||||
main: {
|
||||
allowlist: ["ls", { pattern: "/usr/bin/cat" }, "echo"],
|
||||
},
|
||||
},
|
||||
} as unknown as ExecApprovalsFile;
|
||||
|
||||
const normalized = normalizeExecApprovals(file);
|
||||
const entries = normalized.agents?.main?.allowlist ?? [];
|
||||
|
||||
expect(entries).toHaveLength(3);
|
||||
expect(entries.map((e) => e.pattern)).toEqual(["ls", "/usr/bin/cat", "echo"]);
|
||||
for (const entry of entries) {
|
||||
expect(entry).not.toHaveProperty("0");
|
||||
}
|
||||
});
|
||||
|
||||
it("drops empty string entries", () => {
|
||||
const file = {
|
||||
version: 1,
|
||||
agents: {
|
||||
main: {
|
||||
allowlist: ["", " ", "ls"],
|
||||
},
|
||||
},
|
||||
} as unknown as ExecApprovalsFile;
|
||||
|
||||
const normalized = normalizeExecApprovals(file);
|
||||
const entries = normalized.agents?.main?.allowlist ?? [];
|
||||
|
||||
// Only "ls" should survive; empty/whitespace strings should be dropped
|
||||
expect(entries.map((e) => e.pattern)).toEqual(["ls"]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user