3 Commits

  • fix(security): add host/origin allowlist + validate git refs + quote workflow input (#2185)
    Three defense-in-depth fixes around untrusted input flowing to subprocess execution:
    
    1. **Control-pane HTTP server (scripts/lib/control-pane/server.js)**
       The local control-pane API binds to 127.0.0.1 but had no Host or Origin
       validation, so a DNS-rebinding attack from a malicious website could pivot
       into the loopback endpoints — including POST /api/actions/:id, which spawns
       'cargo run -- graph ...' with caller-supplied query strings. Add a hostname
       allowlist (loopback variants plus the explicitly configured --host) and
       reject mismatched Host (421) or non-loopback Origin (403) before any route
       handler runs.
    
    2. **OpenCode git-summary tool (.opencode/tools/git-summary.ts)**
       The tool was building 'git diff ${baseBranch}...HEAD --stat' with execSync
       and a raw model-supplied baseBranch string. Switch run() to execFileSync
       with an args array (no shell), validate baseBranch against a conservative
       git-ref allowlist (rejects shell metacharacters, leading -, embedded ..),
       and clamp the depth arg to a small positive integer before interpolating
       into 'git log --oneline -<N>'.
    
    3. **Reusable test workflow (.github/workflows/reusable-test.yml)**
       The 'Install dependencies' step interpolated ${{ inputs.package-manager }}
       directly into a bash 'case' and into an echo, so a downstream caller that
       forwarded attacker-controllable input could inject into the runner. Move
       the input into a PACKAGE_MANAGER env var and reference $PACKAGE_MANAGER
       inside the script per the GitHub script-injection guidance.
    
    Detected by Aeon + semgrep p/security-audit (host check via threat-model
    manual-review axis; git-summary via detect-child-process; workflow via
    run-shell-injection).
    
    Verification: node tests/run-all.js — 2686/2687 pre-existing tests pass; the
    one failure (observe.sh legacy output fallback) reproduces on main without
    this branch applied. Added 2 new control-pane tests covering the allowlist
    classifier and the DNS-rebinding-gate behavior end-to-end.
    
    ---
    Filed by [Aeon](https://github.com/aaronjmars/aeon-aaron).
    
    Co-authored-by: aeonframework <aeon@aaronjmars.com>
  • feat: add dynamic workflow team orchestration surface
    Adds dynamic workflow/team orchestration skills, the content pack, and control-pane work-item/Kanban state DB support. Includes reviewer hardening for state-db CLI validation, optional state DB failure handling, and mergeStateStatus projection.
  • feat: add ECC2 local control pane (#2131)
    * feat: add ECC2 local control pane
    
    * fix: refresh control pane package locks
    
    * test: harden control pane coverage
    
    * test: allow portable control pane shutdown
    
    * test: retry local control pane fetches
    
    * fix: harden control pane error handling
    
    * fix: wrap control pane metadata