mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 20:11:23 +00:00
test: add env -S allowlist bypass regressions
This commit is contained in:
@@ -68,6 +68,9 @@ describe("browser control server", () => {
|
||||
cdpUrl: state.cdpBaseUrl,
|
||||
targetId: "abcd1234",
|
||||
url: "https://example.com",
|
||||
ssrfPolicy: {
|
||||
dangerouslyAllowPrivateNetwork: true,
|
||||
},
|
||||
});
|
||||
|
||||
const click = await postJson<{ ok: boolean }>(`${base}/act`, {
|
||||
|
||||
@@ -254,6 +254,35 @@ describe("exec approvals command resolution", () => {
|
||||
expect(resolution?.rawExecutable).toBe("/usr/bin/env");
|
||||
});
|
||||
|
||||
it("fails closed for env -S even when env itself is allowlisted", () => {
|
||||
const dir = makeTempDir();
|
||||
const binDir = path.join(dir, "bin");
|
||||
fs.mkdirSync(binDir, { recursive: true });
|
||||
const envName = process.platform === "win32" ? "env.exe" : "env";
|
||||
const envPath = path.join(binDir, envName);
|
||||
fs.writeFileSync(envPath, process.platform === "win32" ? "" : "#!/bin/sh\n");
|
||||
if (process.platform !== "win32") {
|
||||
fs.chmodSync(envPath, 0o755);
|
||||
}
|
||||
|
||||
const analysis = analyzeArgvCommand({
|
||||
argv: [envPath, "-S", 'sh -c "echo pwned"'],
|
||||
cwd: dir,
|
||||
env: makePathEnv(binDir),
|
||||
});
|
||||
const allowlistEval = evaluateExecAllowlist({
|
||||
analysis,
|
||||
allowlist: [{ pattern: envPath }],
|
||||
safeBins: normalizeSafeBins([]),
|
||||
cwd: dir,
|
||||
});
|
||||
|
||||
expect(analysis.ok).toBe(true);
|
||||
expect(analysis.segments[0]?.resolution?.policyBlocked).toBe(true);
|
||||
expect(allowlistEval.allowlistSatisfied).toBe(false);
|
||||
expect(allowlistEval.segmentSatisfiedBy).toEqual([null]);
|
||||
});
|
||||
|
||||
it("unwraps env wrapper with shell inner executable", () => {
|
||||
const resolution = resolveCommandResolutionFromArgv(["/usr/bin/env", "bash", "-lc", "echo hi"]);
|
||||
expect(resolution?.rawExecutable).toBe("bash");
|
||||
|
||||
@@ -150,7 +150,6 @@ describe("handleSystemRunInvoke mac app exec host routing", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("denies ./sh wrapper spoof in allowlist on-miss mode before execution", async () => {
|
||||
const marker = path.join(os.tmpdir(), `openclaw-wrapper-spoof-${process.pid}-${Date.now()}`);
|
||||
const runCommand = vi.fn(async () => {
|
||||
@@ -213,4 +212,21 @@ describe("handleSystemRunInvoke mac app exec host routing", () => {
|
||||
// no-op
|
||||
}
|
||||
});
|
||||
|
||||
it("denies env -S shell payloads in allowlist mode", async () => {
|
||||
const { runCommand, sendInvokeResult } = await runSystemInvoke({
|
||||
preferMacAppExecHost: false,
|
||||
security: "allowlist",
|
||||
command: ["env", "-S", 'sh -c "echo pwned"'],
|
||||
});
|
||||
expect(runCommand).not.toHaveBeenCalled();
|
||||
expect(sendInvokeResult).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
ok: false,
|
||||
error: expect.objectContaining({
|
||||
message: expect.stringContaining("allowlist miss"),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user