From ca1fe823018295daa97146ce1142b7ad98aae21c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 13:12:32 +0000 Subject: [PATCH] fix(security): catch all-wildcard allow patterns in exec approval policy ValidateExecApprovalRules rejected single '*' but missed patterns like '**', '***', '?', '? *', '* ?' that also match any command string. An agent that can call system.execApprovals.set could bypass the broad-allow restriction by submitting '**' as an allow pattern: {"rules": [{"pattern": "**", "action": "allow"}], "baseHash": "..."} The glob-to-regex translation turns '**' into '^.*.*$', which matches every command, exactly like '*' does. Fix: strip all wildcard chars ('*', '?') and whitespace from the normalised pattern before checking. If nothing remains the pattern is an all-wildcard glob and is rejected as broad. The explicit shell- prefix checks (powershell *, pwsh *, cmd *, cmd.exe *) are preserved for patterns that contain meaningful content but are still too broad. Tests: add **, ***, ?, '? *', '* ?' to ExecApprovalsSet_RejectsUnsafeAllowRules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/OpenClaw.Shared/Capabilities/SystemCapability.cs | 12 +++++++++++- tests/OpenClaw.Shared.Tests/CapabilityTests.cs | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/OpenClaw.Shared/Capabilities/SystemCapability.cs b/src/OpenClaw.Shared/Capabilities/SystemCapability.cs index 773e492..337e7e0 100644 --- a/src/OpenClaw.Shared/Capabilities/SystemCapability.cs +++ b/src/OpenClaw.Shared/Capabilities/SystemCapability.cs @@ -630,7 +630,17 @@ public class SystemCapability : NodeCapabilityBase return "Empty allow rule patterns are not permitted."; var normalized = pattern.ToLowerInvariant(); - if (normalized is "*" or "* *" or "powershell *" or "pwsh *" or "cmd *" or "cmd.exe *") + + // Catch all-wildcard patterns (e.g. *, **, ?*, * ?) that match any command. + // Strip every wildcard character and whitespace; if nothing remains the pattern + // is effectively "match everything" and must be blocked regardless of spelling. + var nonWildcardContent = normalized.Replace("*", "").Replace("?", "").Trim(); + if (string.IsNullOrEmpty(nonWildcardContent)) + return $"Broad allow rule is not permitted: {pattern}"; + + // Catch shell-prefixed blanket patterns that match all commands in a given shell + // (e.g. "powershell *" allows every PowerShell command). + if (normalized is "powershell *" or "pwsh *" or "cmd *" or "cmd.exe *") return $"Broad allow rule is not permitted: {pattern}"; foreach (var dangerous in DangerousAllowPatternFragments) diff --git a/tests/OpenClaw.Shared.Tests/CapabilityTests.cs b/tests/OpenClaw.Shared.Tests/CapabilityTests.cs index 57dacb4..472c883 100644 --- a/tests/OpenClaw.Shared.Tests/CapabilityTests.cs +++ b/tests/OpenClaw.Shared.Tests/CapabilityTests.cs @@ -553,6 +553,11 @@ public class SystemCapabilityTests [Theory] [InlineData("*")] + [InlineData("**")] + [InlineData("***")] + [InlineData("?")] + [InlineData("? *")] + [InlineData("* ?")] [InlineData("cmd *")] [InlineData("Remove-Item *")] [InlineData("Invoke-WebRequest *")]