Skip to content

fix(commands): require trusted session for /mcp and /plugins#6002

Merged
bug-ops merged 1 commit into
mainfrom
fix/5997-mcp-plugins-auth-bypass
Jul 11, 2026
Merged

fix(commands): require trusted session for /mcp and /plugins#6002
bug-ops merged 1 commit into
mainfrom
fix/5997-mcp-plugins-auth-bypass

Conversation

@bug-ops

@bug-ops bug-ops commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #5997

Test plan

  • cargo +nightly fmt --check
  • cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings
  • cargo nextest run --config-file .github/nextest.toml -p zeph-commands (137 passed)
  • RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --all-features -p zeph-commands
  • New regression tests exercise the real CommandRegistry::dispatch gate, not just the trait method

@github-actions github-actions Bot added documentation Improvements or additions to documentation rust Rust code changes bug Something isn't working size/M Medium PR (51-200 lines) labels Jul 11, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 11, 2026 00:04
McpCommand and PluginsCommand left requires_auth() at its default
false, so untrusted remote channels (Telegram/Discord/Slack/gateway)
could invoke /mcp add to spawn an arbitrary local subprocess with the
default allowed_commands allowlist, or /plugins add to install a
plugin from an arbitrary local path, with no authentication. Both
handlers now override requires_auth() to return true, matching the
same defect class already fixed for /image.
@bug-ops
bug-ops force-pushed the fix/5997-mcp-plugins-auth-bypass branch from b02fbeb to 528bc49 Compare July 11, 2026 00:18
@bug-ops
bug-ops merged commit 5fc3556 into main Jul 11, 2026
43 checks passed
@bug-ops
bug-ops deleted the fix/5997-mcp-plugins-auth-bypass branch July 11, 2026 00:26
bug-ops added a commit that referenced this pull request Jul 13, 2026
… durable replay dedup (#6203)

CommandHandler::requires_auth() defaulted to false (accessible from all
channels), a recurring defect class where new handlers silently stayed
reachable from untrusted remote channels until an audit caught them (4th
recurrence: #5967/#5988, #5997/#6002, #6003/PR#6033). Flip the default to
true (fail-closed); the six previously-implicit read-only handlers now
override it explicitly to preserve behavior.

Also fixes durable subagent replay's channel-notify side effects, which
bypassed the ctx.step() dedup discipline (spec-064 INV-10): a resumed
parent could refire the "replayed from durable journal" notice on every
restart. Rather than gating via ctx.step (found to break step-id
determinism between fresh and replay runs), dedup via an out-of-band
notified_at claim column on durable_promises, consuming no step id.

Tightens the doc comment on resolve_durable_spawn_gate's still-pending
resume branch to make the LocalBackend-only safety rationale explicit
at the call site.

Closes #6034
Closes #6027
Closes #6010
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation rust Rust code changes size/M Medium PR (51-200 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SECURITY: /mcp add allows unauthenticated remote code execution via missing requires_auth (default-config exploitable); /plugins add has the same gap

1 participant