Skip to content

fix(mcp): validate MCP server commands and harden defaults (issue #14) - #34

Merged
labtgbot merged 1 commit into
mainfrom
issue-14-mcp-command-validation
Jun 15, 2026
Merged

fix(mcp): validate MCP server commands and harden defaults (issue #14)#34
labtgbot merged 1 commit into
mainfrom
issue-14-mcp-command-validation

Conversation

@xdevrobot

Copy link
Copy Markdown
Collaborator

Summary

Fixes CWE-78 (OS Command Injection) — MCP server commands from config.yaml were spawned without any validation, allowing arbitrary command execution.

Changes

src/agent/tools/mcp-loader.ts

  • Added ALLOWED_MCP_COMMANDS allowlist (npx, node, python3, python, uvx, deno, bun)
  • Added validateMcpCommand() — rejects commands containing shell metacharacters and commands not in the allowlist
  • Extended BLOCKED_ENV_KEYS with 13 additional dangerous env vars (DYLD_LIBRARY_PATH, NODE_EXTRA_CA_CERTS, PYTHONPATH, PYTHONSTARTUP, PYTHONINSPECT, RUBYLIB, PERL5LIB, PERLLIB, SSL_CERT_FILE, SSL_CERT_DIR, ELECTRON_RUN_AS_NODE)
  • Changed default MCP server scope from "always" to "admin-only"

src/config/schema.ts

  • Changed McpServerSchema scope default from "always" to "admin-only"
  • Exported McpServerSchema for use in tests

src/agent/tools/tests/mcp-loader.test.ts (new)

  • 17 tests covering: command validation, allowlist enforcement, metacharacter detection, schema defaults, blocked env keys

Security Impact

  • Prevents arbitrary command execution via malicious config.yaml MCP server entries
  • Prevents library injection via environment variables passed to MCP child processes
  • Least-privilege default: MCP tools now require admin scope by default

Closes #14

🤖 Generated with Claude Code

Prevents CWE-78 arbitrary command execution through MCP server config.
Commands from config.yaml are now validated against an allowlist and
checked for shell metacharacters before spawning.

Changes:
- mcp-loader.ts: Add ALLOWED_MCP_COMMANDS allowlist (npx, node, python3,
  python, uvx, deno, bun) — rejects unknown binaries and absolute paths
  outside allowed set
- mcp-loader.ts: Add validateMcpCommand() — rejects commands containing
  shell metacharacters (|, ;, &, $, (), `, {}, \)
- mcp-loader.ts: Extend BLOCKED_ENV_KEYS with DYLD_LIBRARY_PATH,
  NODE_EXTRA_CA_CERTS, PYTHONPATH, PYTHONSTARTUP, PYTHONINSPECT,
  RUBYLIB, PERL5LIB, PERLLIB, SSL_CERT_FILE, SSL_CERT_DIR, PATH, HOME
- mcp-loader.ts: Change default scope from "always" to "admin-only"
- schema.ts: Export McpServerSchema for testing
- schema.ts: Change McpServerSchema scope default from "always" to "admin-only"
- New test file: mcp-loader.test.ts — 17 tests covering command validation,
  allowlist enforcement, metacharacter detection, schema defaults,
  blocked env keys, and config parsing

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@labtgbot
labtgbot merged commit 2f82064 into main Jun 15, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HIGH][CWE-78] MCP server commands from config.yaml are spawned unvalidated

2 participants