Skip to content

security: Sanitize worktreeSetup.commands before shell execution #24

@nigel-dev

Description

@nigel-dev

Description

The `worktreeSetup.commands` config option allows arbitrary shell commands to be executed via `sh -c` without any sanitization or validation. While the config file is user-controlled, this creates a risk if configs are shared, checked into repos, or if the config parsing is ever exposed to untrusted input.

Current Implementation

```typescript
// src/lib/worktree.ts:140
if (hooks.commands) {
for (const cmd of hooks.commands) {
const proc = spawn(['sh', '-c', cmd], {
cwd: worktreePath,
// ...
});
}
}
```

Note: `worktree-setup.ts` does validate `copyFiles` and `symlinkDirs` with `isUnsafePath()`, but `commands` are passed through with no checks at all.

Risk Assessment

  • Current risk: Low — configs are local user files.
  • Future risk: Medium — if MC ever supports shared config, team templates, or plan recipes, these commands become a vector.
  • Audit note: The README mentions `worktreeSetup.commands` but the audit flags: "Commands are NOT sanitized — arbitrary shell execution via config."

Proposed Solution

  1. Allowlist approach (recommended): Define a set of safe command patterns (e.g., package manager installs, build commands) and validate against them. Reject or warn on unrecognized patterns.
  2. Logging approach (minimal): Log all commands before execution with a clear warning if they contain potentially dangerous patterns (pipes, redirects, backticks, `$(...)`).
  3. Confirmation approach: For commands that don't match safe patterns, require explicit user confirmation or a config flag like `allowUnsafeCommands: true`.

Files Involved

  • `src/lib/worktree.ts:140` — command execution
  • `src/lib/worktree-setup.ts` — hook resolution (validates paths but not commands)
  • `src/lib/config.ts` — config loading

Additional Context

From audit report Appendix B: "worktreeSetup.commands — Commands are NOT sanitized — arbitrary shell execution via config."

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1: highImportant fix or feature — next up after criticalbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions