mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 01:21:25 +00:00
fix(exec): allow heredoc operator (<<) in allowlist security mode (#13811)
* fix(exec): allow heredoc operator (<<) in allowlist security mode * fix: allow multiline heredoc parsing in exec approvals (#13811) (thanks @mcaxtr) --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -164,6 +164,68 @@ describe("exec approvals shell parsing", () => {
|
||||
expect(res.segments[0]?.argv[0]).toBe("echo");
|
||||
});
|
||||
|
||||
it("rejects input redirection (<)", () => {
|
||||
const res = analyzeShellCommand({ command: "cat < input.txt" });
|
||||
expect(res.ok).toBe(false);
|
||||
expect(res.reason).toBe("unsupported shell token: <");
|
||||
});
|
||||
|
||||
it("rejects output redirection (>)", () => {
|
||||
const res = analyzeShellCommand({ command: "echo ok > output.txt" });
|
||||
expect(res.ok).toBe(false);
|
||||
expect(res.reason).toBe("unsupported shell token: >");
|
||||
});
|
||||
|
||||
it("allows heredoc operator (<<)", () => {
|
||||
const res = analyzeShellCommand({ command: "/usr/bin/tee /tmp/file << 'EOF'" });
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.segments[0]?.argv[0]).toBe("/usr/bin/tee");
|
||||
});
|
||||
|
||||
it("allows heredoc without space before delimiter", () => {
|
||||
const res = analyzeShellCommand({ command: "/usr/bin/tee /tmp/file <<EOF" });
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.segments[0]?.argv[0]).toBe("/usr/bin/tee");
|
||||
});
|
||||
|
||||
it("allows heredoc with strip-tabs operator (<<-)", () => {
|
||||
const res = analyzeShellCommand({ command: "/usr/bin/cat <<-DELIM" });
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.segments[0]?.argv[0]).toBe("/usr/bin/cat");
|
||||
});
|
||||
|
||||
it("allows heredoc in pipeline", () => {
|
||||
const res = analyzeShellCommand({ command: "/usr/bin/cat << 'EOF' | /usr/bin/grep pattern" });
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.segments).toHaveLength(2);
|
||||
expect(res.segments[0]?.argv[0]).toBe("/usr/bin/cat");
|
||||
expect(res.segments[1]?.argv[0]).toBe("/usr/bin/grep");
|
||||
});
|
||||
|
||||
it("allows multiline heredoc body", () => {
|
||||
const res = analyzeShellCommand({
|
||||
command: "/usr/bin/tee /tmp/file << 'EOF'\nline one\nline two\nEOF",
|
||||
});
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.segments[0]?.argv[0]).toBe("/usr/bin/tee");
|
||||
});
|
||||
|
||||
it("allows multiline heredoc body with strip-tabs operator (<<-)", () => {
|
||||
const res = analyzeShellCommand({
|
||||
command: "/usr/bin/cat <<-EOF\n\tline one\n\tline two\n\tEOF",
|
||||
});
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.segments[0]?.argv[0]).toBe("/usr/bin/cat");
|
||||
});
|
||||
|
||||
it("rejects multiline commands without heredoc", () => {
|
||||
const res = analyzeShellCommand({
|
||||
command: "/usr/bin/echo first line\n/usr/bin/echo second line",
|
||||
});
|
||||
expect(res.ok).toBe(false);
|
||||
expect(res.reason).toBe("unsupported shell token: \n");
|
||||
});
|
||||
|
||||
it("rejects windows shell metacharacters", () => {
|
||||
const res = analyzeShellCommand({
|
||||
command: "ping 127.0.0.1 -n 1 & whoami",
|
||||
|
||||
Reference in New Issue
Block a user