diff --git a/pkg/tools/shell.go b/pkg/tools/shell.go index 3d5a97fe..95690f16 100644 --- a/pkg/tools/shell.go +++ b/pkg/tools/shell.go @@ -1162,7 +1162,7 @@ func (t *ExecTool) guardCommand(command, cwd string) string { } } - if len(t.allowPatterns) > 0 || len(t.customAllowPatterns) > 0 { + if len(t.allowPatterns) > 0 { if !t.commandMatchesAllowPattern(lower) { return "Command blocked by safety guard (not in allowlist)" } diff --git a/pkg/tools/shell_test.go b/pkg/tools/shell_test.go index 5312283b..a3399ede 100644 --- a/pkg/tools/shell_test.go +++ b/pkg/tools/shell_test.go @@ -1970,3 +1970,20 @@ func TestShellTool_CustomAllowStillPermitsSafeMatch(t *testing.T) { t.Fatalf("safe custom-allowed command should pass guard, got: %q", got) } } + +func TestShellTool_CustomAllowDoesNotBecomeStrictAllowlist(t *testing.T) { + cfg := &config.Config{} + cfg.Tools.Exec.EnableDenyPatterns = true + cfg.Tools.Exec.CustomAllowPatterns = []string{`^jq\b`} + cfg.Tools.Exec.CustomDenyPatterns = []string{`\$env\b`, `(^|[^.$a-z0-9_])env([^a-z0-9_]|$)`} + + tool, err := NewExecToolWithConfig(t.TempDir(), false, cfg) + if err != nil { + t.Fatalf("NewExecToolWithConfig() error: %v", err) + } + + got := tool.guardCommand("ls", t.TempDir()) + if got != "" { + t.Fatalf("custom allow patterns should not become a strict allowlist, got: %q", got) + } +}