Skip to content

auto-loaded ./mcpls.toml executes arbitrary command/args/env with no confirmation #229

Description

@bug-ops

Description

mcpls auto-discovers and loads ./mcpls.toml from the current working directory on startup (config/mod.rs, default config path resolution), and each [[lsp_servers]] entry's command, args, and env are passed directly to Command::new (lsp/lifecycle.rs) with no confirmation, allowlist, or sandboxing step.

Since mcpls is designed to be launched by an AI coding agent against an arbitrary working directory (e.g. a freshly cloned repository), a hostile repository can ship an mcpls.toml that spawns an arbitrary process — with attacker-controlled args and env — the moment mcpls starts, before any LSP-specific validation occurs. This is effectively code execution via git clone <hostile-repo> && <start mcpls in that directory>.

This was identified as a side finding during the security review for #174/#165 (routing config work) — it is a pre-existing gap unrelated to that PR's scope, so it wasn't fixed there.

Reproduction Steps

  1. Create a repository containing mcpls.toml with an [[lsp_servers]] entry whose command points to an arbitrary executable (e.g. a script that exfiltrates data or opens a reverse shell), disguised with a plausible language_id/file_patterns.
  2. Clone the repository.
  3. Start mcpls with that directory as the workspace root (as an AI agent integration normally would).
  4. Observe: the configured command executes immediately as part of server discovery/spawn, with no prompt or confirmation.

Expected Behavior

At minimum, one of:

  • mcpls warns or requires explicit confirmation before executing a command sourced from a project-local (not user/global) config file it did not create.
  • A documented trust boundary: e.g. only global/user-level config (~/.config/mcpls/mcpls.toml, $MCPLS_CONFIG) is auto-loaded without confirmation; project-local ./mcpls.toml requires an explicit opt-in flag or first-run prompt, similar to how VS Code / direnv handle untrusted workspace config.

Actual Behavior

./mcpls.toml in the current directory is auto-loaded and its command/args/env are executed unconditionally on startup.

Environment

  • Version: current main (0.3.7)
  • Files: crates/mcpls-core/src/config/mod.rs (auto-load path resolution), crates/mcpls-core/src/lsp/lifecycle.rs (Command::new spawn)

Logs / Evidence

Flagged during the security-audit validation pass for PR #228 (issues #174/#165): "the config is already an arbitrary-code-execution boundary — ./mcpls.toml in the current directory is auto-loaded and its command/args/env go straight to Command::new. Cloning a hostile repository and starting mcpls in it is code execution."

Metadata

Metadata

Assignees

Labels

P1High: degraded UX, incorrect non-destructive behaviorbugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions