Problem
command.run checks the allowlist using string equality/prefix matching, then executes the full command through a shell.
Relevant code:
command === allowed || command.startsWith(`${allowed} `)
await execAsync(command, ...)
With allowlist ["echo"], a command such as echo ok; rm -rf /tmp/foo passes the allowlist and is executed by the shell.
Impact
High-risk command injection if command.run is exposed to untrusted or semi-trusted callers.
Suggested fix
- Avoid
exec; use spawn/execFile with parsed argv.
- Allowlist by executable plus validated arguments.
- Alternatively reject shell metacharacters and document limitations.
- Consider disabling
command.run unless explicitly configured.
Acceptance criteria
- Allowlisted command names cannot be used to smuggle shell metacharacters or additional commands.
- Tests cover cases like
echo ok; uname -a with AGENTDISPATCH_COMMAND_ALLOWLIST=echo.
Problem
command.runchecks the allowlist using string equality/prefix matching, then executes the full command through a shell.Relevant code:
src/index.ts:118-128With allowlist
["echo"], a command such asecho ok; rm -rf /tmp/foopasses the allowlist and is executed by the shell.Impact
High-risk command injection if
command.runis exposed to untrusted or semi-trusted callers.Suggested fix
exec; usespawn/execFilewith parsed argv.command.rununless explicitly configured.Acceptance criteria
echo ok; uname -awithAGENTDISPATCH_COMMAND_ALLOWLIST=echo.