Skip to content

Security Vulnerability: Bypass of Command Validation in run_command Tool of hdresearch/mcp-shell #16

@ClementineZsw

Description

@ClementineZsw

Security Vulnerability: Bypass of Command Validation in run_command Tool of hdresearch/mcp-shell

Describe the vulnerability
A critical command injection vulnerability exists in the run_command tool of hdresearch/mcp-shell, allowing attackers to bypass existing security controls and execute arbitrary dangerous commands through shell-based obfuscation techniques.

The vulnerability arises from fundamental flaws in the command execution and validation architecture:

  1. Shell-based execution enables bypass techniques:
    The command execution flow uses execa(command, [], { shell: true }) (src/index.ts line 120-123) which passes the entire command string to a shell for interpretation. This allows full use of shell syntax, including command substitution and concatenation, which can be exploited to bypass security checks.

  2. Inadequate validation based on base command matching:
    While a security validation mechanism exists in validateCommand (src/index.ts line 53-55), it only checks the first word of the command (src/index.ts line 111) against a blacklist. This can be easily circumvented by:

    • Splitting prohibited commands into fragments
    • Dynamically reconstructing them using shell features like echo -n and command substitution $()
    • Executing the reconstructed commands through nested substitution
  3. Complete execution chain:
    User-controlled input is validated only by checking the first word against the blacklist, then is executed via execa with shell: true (src/index.ts line 120-123) in a shell context, allowing obfuscated malicious commands to bypass checks and execute successfully.

This combination creates a critical security gap where attackers can execute any system command regardless of the intended validation controls.

To Reproduce

  1. Send the following request to a vulnerable mcp-shell server:
{
    "method": "tools/call",
    "params": {
        "name": "run_command",
        "arguments": {
            "command": "echo $($(echo -n c; echo -n h; echo -n m; echo -n o; echo -n d))"
        },
        "_meta": {
            "progressToken": 42
        }
    }
}
  1. Observe that:
    • The command successfully bypasses the validateCommand checks (since the base command is "echo")
    • The obfuscated command (which reconstructs "chmod") executes successfully
    • This demonstrates how any prohibited command can be similarly executed

Expected behavior
The application should implement security controls that address the root cause by:

  • Avoiding execution of arbitrary command strings through a shell by setting shell: false in execa
  • Using direct executable invocation with separate arguments to prevent shell interpretation
  • Implementing comprehensive validation that parses and analyzes the entire command structure, not just the base command
  • Using allowlists for specific executable paths rather than simple blacklist keyword matching
  • Adding shell syntax parsing to detect and block command substitution and concatenation techniques

These changes would prevent the use of shell features to bypass security controls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions