mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 04:21:24 +00:00
refactor(security): refine safeBins hardening
This commit is contained in:
@@ -5,7 +5,7 @@ import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
analyzeArgvCommand,
|
||||
analyzeShellCommand,
|
||||
buildSafeShellCommand,
|
||||
buildSafeBinsShellCommand,
|
||||
evaluateExecAllowlist,
|
||||
evaluateShellAllowlist,
|
||||
isSafeBinUsage,
|
||||
@@ -80,21 +80,30 @@ describe("exec approvals allowlist matching", () => {
|
||||
});
|
||||
|
||||
describe("exec approvals safe shell command builder", () => {
|
||||
it("single-quotes argv tokens while preserving pipes/chaining", () => {
|
||||
it("quotes only safeBins segments (leaves other segments untouched)", () => {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
}
|
||||
const res = buildSafeShellCommand({
|
||||
command: 'head $FOO | grep * && echo "a\'b" ; wc -l',
|
||||
|
||||
const analysis = analyzeShellCommand({
|
||||
command: "rg foo src/*.ts | head -n 5 && echo ok",
|
||||
cwd: "/tmp",
|
||||
env: { PATH: "/usr/bin:/bin" },
|
||||
platform: process.platform,
|
||||
});
|
||||
expect(analysis.ok).toBe(true);
|
||||
|
||||
const res = buildSafeBinsShellCommand({
|
||||
command: "rg foo src/*.ts | head -n 5 && echo ok",
|
||||
segments: analysis.segments,
|
||||
segmentSatisfiedBy: [null, "safeBins", null],
|
||||
platform: process.platform,
|
||||
});
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.command).toContain("'$FOO'");
|
||||
expect(res.command).toContain("'*'");
|
||||
expect(res.command).toContain("&&");
|
||||
expect(res.command).toContain(";");
|
||||
expect(res.command).toContain("|");
|
||||
expect(res.command).toContain("'a'\"'\"'b'");
|
||||
// Preserve non-safeBins segment raw (glob stays unquoted)
|
||||
expect(res.command).toContain("rg foo src/*.ts");
|
||||
// SafeBins segment is fully quoted
|
||||
expect(res.command).toContain("'head' '-n' '5'");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -346,6 +355,9 @@ describe("exec approvals shell allowlist (chained commands)", () => {
|
||||
|
||||
describe("exec approvals safe bins", () => {
|
||||
it("allows safe bins with non-path args", () => {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
}
|
||||
const dir = makeTempDir();
|
||||
const binDir = path.join(dir, "bin");
|
||||
fs.mkdirSync(binDir, { recursive: true });
|
||||
@@ -370,6 +382,9 @@ describe("exec approvals safe bins", () => {
|
||||
});
|
||||
|
||||
it("blocks safe bins with file args", () => {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
}
|
||||
const dir = makeTempDir();
|
||||
const binDir = path.join(dir, "bin");
|
||||
fs.mkdirSync(binDir, { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user