mcpField
C
Command Injection Vulnerability in MCP File Reader

Command Injection Vulnerability in MCP File Reader

Local
github.com/Eliran79Developer Tools3Updated 78w ago

About Command Injection Vulnerability in MCP File Reader

A deliberately vulnerable Python MCP server for security education. It demonstrates how unsanitized file paths in `read_file` can enable shell command execution, and is explicitly not for production use.

Key features

  1. 01Demonstrates command injection in file reading
  2. 02Exposes a `read_file` tool
  3. 03Shows unsafe shell invocation
  4. 04Includes remediation examples

Use cases

  1. 01Study command injection in MCP servers
  2. 02Demonstrate risks of unsanitized paths
  3. 03Review safer subprocess and path handling

MCP support

Exposes the `read_file` tool to MCP clients. The tool illustrates a command injection flaw through its handling of file paths.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

Command Injection Vulnerability in MCP File Reader

This repository demonstrates a critical command injection vulnerability in a Python MCP (Model Context Protocol) server implementation. The vulnerability allows attackers to execute arbitrary shell commands on the host system by manipulating the file path parameter.

The Vulnerability

The vulnerability exists in the read_file function which is intended to read files from a "safe" directory but contains a dangerous implementation flaw:

command = f"cat {file_name}"
result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)

This code is vulnerable because:

  1. It uses shell=True which invokes a shell to execute the command
  2. It directly interpolates user input (file_name) into the command string without proper sanitization
  3. It performs only superficial validation on the input path

A simple semantic difference between using quotes around the filename ('file_name') and not using quotes (file_name) exposes the entire system to command execution.

Installation

Prerequisites
  • Python 3.12 or higher
  • MCP library version 1.6.0
Setup
  1. Clone this repository:

    git clone https://github.com/Eliran79/Vulnerable-file-reader-server.git
    cd Vulnerable-file-reader-server
    
  2. Install the MCP server:

    mcp install main.py
    
  3. Configure Claude Desktop to use your MCP server by editing ~/.config/claude-desktop/claude_desktop_config.json:

    {
      "mcpServers": {
        "file-reader": {
          "command": "/ABSOLUTE/PATH/TO/uv",
          "args": [
            "--directory",
            "/data/git/file_reader_server",
            "/usr/bin/uv",
            "run,--with,mcp,mcp,run,main.py"
          ]
        }
      }
    }
    

    Be sure to replace /ABSOLUTE/PATH/TO/uv with the actual path to your uv executable and adjust the directory path if needed.

  4. Start the MCP server in development mode:

    mcp dev main.py
    

Demonstration

  1. In a separate terminal, install and run the MCP inspector:

    pip install mcp-inspector
    mcp-inspector
    
  2. Connect to the server in the MCP Inspector GUI:

    • Set Transport Type to "STDIO"
    • Set Command to: run --with mcp run main.py
    • Click "Restart"
  3. Exploit the vulnerability:

    • Go to the "Tools" tab
    • Find the "read_file" tool
    • In the "file_name" field, enter:
      /tmp/safe/test.txt; whoami
      
    • Click "Run Tool"
  4. You should see the contents of test.txt followed by your username, demonstrating successful command execution.

Additional Exploitation Examples

Here are more command injection payloads to try:

/tmp/safe/test.txt; id
/tmp/safe/test.txt; ls -la /etc
/tmp/safe/test.txt; cat /etc/passwd
/tmp/safe/test.txt; echo $(hostname)
/tmp/safe/test.txt; find / -name "*.conf" 2>/dev/null | head -5

Proper Fix

To fix this vulnerability, never use shell=True with user-provided input. Instead:

# SECURE: Use a list of arguments instead of shell=True
result = subprocess.check_output(['cat', file_name], shell=False)

# OR, if shell=True is necessary, properly quote the argument:
import shlex
result = subprocess.check_output(f"cat {shlex.quote(file_name)}", shell=True)

# AND perform proper path validation:
import os
safe_dir_resolved = os.path.abspath(SAFE_DIRECTORY)
requested_path_resolved = os.path.abspath(file_name)
if not requested_path_resolved.startswith(safe_dir_resolved):
    return f"Error: Access denied. Path traversal attempt detected."

Warning

⚠️ FOR EDUCATIONAL PURPOSES ONLY: This implementation contains deliberate security vulnerabilities. Never use this code in a production environment or on any system that contains sensitive information.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.