--- id: DIS-002 status: ready phase: 0 priority: p0 labels: [phase:0, type:fix, priority:p0, security] branch: phase-0/harden-spawn assignee: null started: null pr: null merged: null --- # DIS-002: `shell: false` + `cross-spawn` Windows-Fix im Runner ## Ziel Command-Injection über Discord-User-Input eliminieren. `shell: true` aus `src/agent/runner.ts` entfernen, durch `cross-spawn` ersetzen. Windows-`.cmd`-Wrapper wird korrekt aufgelöst, CVE-2024-27980 umgangen. ## Kontext `src/agent/runner.ts` nutzt aktuell `shell: true` → jeder Discord-Input landet in der Shell-Interpretation. `spawn("claude", args, { shell: false })` schlägt auf Windows fehl (nur `claude.cmd` existiert). → `docs/development-plan.md` §2.2, `docs/cli-feature-answers.md` Frage 9. ## Scope - **In**: `cross-spawn` + `@types/cross-spawn` als Dependencies · `src/runtime/resolve-claude.ts`: `resolveClaude()` liest `CLAUDE_PATH`, fällt auf `where`/`which` zurück, cached in-memory · `runner.ts`: `shell: false`, `windowsHide: true`, `stdio: pipe`, `setEncoding("utf8")` - **Out**: `sanitizedEnv()` (DIS-003) · `--bare`-Flags (DIS-004) ## Definition of Done - [ ] Kein `shell: true` mehr im gesamten `src/`-Baum (`grep -r "shell: true" src/` → leer) - [ ] `cross-spawn` in `package.json#dependencies` - [ ] `resolveClaude()` wirft klare Fehlermeldung wenn `claude` nicht auffindbar - [ ] Unit-Test `tests/unit/resolve-claude.test.ts` deckt: `.env`-Override, PATH-Fallback, Error bei Nichtfund - [ ] `npm run build && npm test` grün ## Dateien (erwartet) - `package.json` - `src/runtime/resolve-claude.ts` - `src/agent/runner.ts` - `tests/unit/resolve-claude.test.ts` ## Abhängigkeiten Keine. **Empfohlener Startpunkt — zuerst lösen.** ## Spec → `docs/backlog.md` #DIS-002