fix(security): prevent arbitrary command execution in McpToolset YAML config#923
Open
Ashutosh0x wants to merge 1 commit into
Open
fix(security): prevent arbitrary command execution in McpToolset YAML config#923Ashutosh0x wants to merge 1 commit into
Ashutosh0x wants to merge 1 commit into
Conversation
… config The McpToolset factory in configurable_utils.go passes user-controlled 'command' and 'args' fields from YAML agent configurations directly to exec.Command() with no validation. This enables arbitrary OS command execution (RCE) when an attacker can influence agent config files. This is analogous to CVE-2026-4810 in adk-python, but more severe because exec.Command() provides direct OS command execution (vs. Python's importlib.import_module() which requires a valid module path). Fix: - Add allowedMCPCommands allowlist restricting MCP server commands to known-safe launchers (npx, node, python, python3, uvx, uv, docker, deno, bun) - Add blockedMCPArgs denylist to detect shell injection patterns in command arguments (;, &&, ||, |, backticks, command substitution, etc.) - Handle full paths (extract basename) and Windows extensions (.exe, .cmd) - Add 42 comprehensive test cases covering allowed, blocked, and edge cases Security impact: Prevents RCE via malicious YAML agent configs that specify arbitrary commands in McpToolset.stdio_connection_params.server_params.command
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
2. Or, if no issue exists, describe the change:
Problem:
The
McpToolsetfactory ininternal/configurable/configurable_utils.gopasses user-controlledcommandandargsfields from YAML agent configurations directly toexec.Command()with no validation, enabling arbitrary OS command execution (RCE) when an attacker can influence agent config files.This is analogous to CVE-2026-4810 in
adk-python, but potentially more severe becauseexec.Command()provides direct OS command execution (vs. Python'simportlib.import_module()which requires a valid module path).Vulnerable code path (
configurable_utils.go:204-227):Attack scenario — a malicious YAML agent config can execute arbitrary commands:
Solution:
Two-layer defense-in-depth validation before
exec.Command()is called:Command Allowlist (
validateMCPCommand): Only known-safe MCP server launchers are permitted:npx,node,python,python3,uvx,uv,docker,deno,bun. Usesfilepath.Base()to handle full paths and strips Windows extensions (.exe,.cmd,.bat).Argument Injection Blocklist (
validateMCPArgs): Detects shell injection patterns in command arguments:;,&&,||,|, backticks,$(,${,>,<, newlines.Alignment with adk-python: This follows the same security hardening pattern applied in adk-python's
config_agent_utils.pywhich added_BLOCKED_MODULESand_BLOCKED_YAML_KEYSto mitigate CVE-2026-4810.Testing Plan
Unit Tests:
42 comprehensive test cases in
mcp_command_validation_test.go:Manual End-to-End (E2E) Tests:
Verified the following scenarios manually:
command: "npx"→ MCP toolset initializes normally ✅command: "/bin/sh"→ returns error"blocked MCP server command"✅args: ["-c", "malicious && payload"]→ returns error"blocked MCP server argument"✅command: "npx.cmd"resolves to allowed"npx"✅command: "/usr/bin/node"resolves to allowed"node"✅Checklist
Additional context
importlib.import_module()_BLOCKED_MODULES/_BLOCKED_YAML_KEYSapproach, adapted for Go'sexec.Command()attack vector