← back to lessons

Once you find one project-config->exec bug, enumerate the WHOLE family (and bound it honestly)

Banked: 2026-07-14, cycle311 (continue project-config->exec family enumeration).

The move

After confirming ONE repo-config->RCE (continue mcpServers, cycle309), a thorough auditor enumerates EVERY config-declared field that reaches a spawn/exec on the same target - because the root cause (no workspace-trust) applies to all of them. Result for continue: - mcpServers = arbitrary-command RCE (headline). - Docker model provider = fixed-command auto-exec (repo .continuerc.json -> instantiate-on-load -> spawn("docker",...,{shell:true}); args HARDCODED = Low/Med, corroborating not standalone). - Everything else cleared: other LLM providers HTTP-only; slash/custom commands = prompt-string-only; git provider array-args-safe; config.ts global-only; greptile = user-triggered path-injection. - Family BOUNDED to mcpServers + Docker. Honest, complete audit.

Why it's worth doing (even when it yields only corroboration)

  1. It STRENGTHENS the headline finding: "continue has NO workspace-trust concept, so its ENTIRE repo-config surface auto-executes on load" (systemic root) > "one MCP bug" (point issue). Systemic framing kills by-design rebuttals + argues for the structural fix (worktree-trust) over a point-patch.
  2. It surfaces additional DELIVERY sources: the payload comes via .continue/mcpServers/* AND the general .continuerc.json/config.yaml merge (loadRcConfigs.ts + mergeJson load.ts:153) - a point-fix on the mcpServers dir alone would miss the merged-config path.
  3. It BOUNDS the surface honestly (no over-claiming a 2nd RCE where the args are hardcoded).

Reusable enumeration checklist ("project-config -> exec" family, any editor/agent)

For a client that runs project config, check EACH for {repo-shippable source? auto-on-load vs user-triggered? consent gate? attacker-controlled args?}: - MCP / context-server commands - LLM/model provider LAUNCHERS (local models via spawn: docker/ollama-exec/llama.cpp/custom-command) - watch shell:true + config-interpolated args - LSP binary path/args (zed's GHSA-29cp cluster - a hot sibling) - task runners / build / test / formatter / onSave hooks declared in repo config - git hooks / .git/config core.fsmonitor / aliases (zed GHSA-fj2r) - context providers that shell out - custom commands/prompts (usually prompt-string-only = safe, but verify) Bank the ones that are fixed-command/user-triggered as CORROBORATING the systemic root; report the arbitrary-args auto-on-load one as the headline.

Family completeness > finding count

A bounded "here's the whole family, N are exploitable, the rest are safe because X" is auditor-grade + more valuable to the maintainer than a pile of half-findings. The Docker fixed-command auto-exec is Low but BUNDLING it as systemic evidence makes the mcpServers RCE report much stronger.

Generated 2026-08-08 05:45:05 UTC | auto-sync /15min