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>
This commit is contained in:
parent
29510a16eb
commit
ca1fe82301
@ -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)
|
||||
|
||||
@ -553,6 +553,11 @@ public class SystemCapabilityTests
|
||||
|
||||
[Theory]
|
||||
[InlineData("*")]
|
||||
[InlineData("**")]
|
||||
[InlineData("***")]
|
||||
[InlineData("?")]
|
||||
[InlineData("? *")]
|
||||
[InlineData("* ?")]
|
||||
[InlineData("cmd *")]
|
||||
[InlineData("Remove-Item *")]
|
||||
[InlineData("Invoke-WebRequest *")]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user