Skip to content

Security

github-actions[bot] edited this page Mar 22, 2026 · 20 revisions

Security

The MATLAB MCP Server implements comprehensive security controls to prevent misuse while keeping MATLAB accessible to AI agents across different deployment scenarios.

Authentication and Authorization

Transport-Level Security

graph LR
    Agent["AI Agent"]
    
    Agent -->|stdio<br/>single session| Server["MCP Server<br/>(Local)"]
    Agent -->|SSE over HTTP<br/>multi-session| Proxy["Reverse Proxy<br/>(nginx, Caddy)"]
    Proxy -->|localhost:8765<br/>authenticated| Server
    
    Server -->|Per-session<br/>isolation| Sessions["Session Manager<br/>Temp Directory Isolation"]
Loading

Stdio Transport (Single User)

  • Default for local development and single-user deployments
  • No authentication mechanism (process-level isolation provided by OS)
  • One implicit "default" session per server instance

SSE Transport (Multi-User)

  • Exposes HTTP endpoints for long-lived connections
  • MUST be deployed behind a reverse proxy with authentication
  • The server does NOT provide built-in authentication (by design)
  • Each authenticated request gets its own session ID
  • Sessions are isolated via dedicated temp directories

Enforcing Proxy Authentication

security:
  require_proxy_auth: true  # Acknowledges reverse proxy is in place
  
server:
  transport: "sse"
  host: "127.0.0.1"         # Bind to localhost only
  port: 8765                # Expose only to proxy

When SSE is enabled without require_proxy_auth: true, the server logs a SECURITY WARNING at startup:

WARNING: SSE transport enabled without require_proxy_auth=true.
This server should only be exposed to the internet via a reverse proxy
with authentication (OAuth2, JWT, mTLS, etc.).

Example nginx reverse proxy with HTTP Basic Auth:

upstream matlab_mcp {
    server localhost:8765;
}

server {
    listen 443 ssl http2;
    server_name matlab.example.com;
    
    ssl_certificate /etc/ssl/certs/matlab.crt;
    ssl_certificate_key /etc/ssl/private/matlab.key;
    
    auth_basic "MATLAB MCP Server";
    auth_basic_user_file /etc/nginx/.htpasswd;
    
    location / {
        proxy_pass http://matlab_mcp;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Input Validation and Sanitization

MATLAB Code Security

The SecurityValidator enforces a blocklist of dangerous functions before code execution:

# From src/matlab_mcp/security/validator.py
blocked_functions = [
    "system",      # Execute arbitrary OS commands
    "unix",        # Execute Unix commands
    "dos",         # Execute DOS/Windows commands
    "!",           # Shell escape operator
    "eval",        # Execute arbitrary string as code
    "feval",       # Call function by name string
    "evalc",       # Evaluate and capture output
    "evalin",      # Evaluate in caller/base workspace
    "assignin",    # Assign variable in caller/base workspace
    "perl",        # Execute Perl scripts
    "python",      # Execute Python scripts
]

Smart Scanning (Avoids False Positives)

The validator strips string literals and comments before pattern matching:

% SAFE (will NOT be blocked):
disp('The operating system is great')    % "system" in string literal
% system('ls')                            % "system" in comment
msg = "unix-based systems";               % "unix" in double-quoted string
function systematic_approach()            % "system" as part of word (boundary check)

% BLOCKED (actual dangerous calls):
system('rm -rf /')                        % system() call
!ls -la                                   % Shell escape
eval('disp(''malicious'')')               % eval() call

Implementation Detail: The regex patterns use \b word boundaries to avoid matching substrings like "systematic", and preprocess code to remove:

  • Single-quoted strings: '...' (with escape handling for '')
  • Double-quoted strings: "..."
  • Line comments: % ...
  • Block comments: %{ ... %}

Filename Validation

All file operations (upload, read, delete) sanitize filenames to prevent path traversal:

# REJECTED (path traversal attempts):
"../../../etc/passwd"
"..\\..\\windows\\system32\\drivers\\etc\\hosts"
"/etc/passwd"
"C:\\Windows\\System32\\config\\SAM"

# ACCEPTED (safe filenames):
"data.csv"
"my_results.mat"
"plot_2024-01-15.png"
"signal_processing-v2.m"

Validation Rules:

  • Characters allowed: [a-zA-Z0-9._-] plus path separators / (normalized to current dir)
  • No leading / or \
  • No .. sequences
  • No special characters that could break filesystem operations

Upload Size Limits

security:
  max_upload_size_mb: 100  # Default 100MB

  # For each file type
  max_mat_file_size_mb: 500
  max_csv_size_mb: 50

Oversized uploads return a failed status with diagnostic:

{
  "status": "failed",
  "error": "Upload size 250MB exceeds limit 100MB"
}

Security-Related Configuration Options

All security settings are in the security: section of config.yaml:

security:
  # Function blocklist enforcement
  blocked_functions_enabled: true
  blocked_functions:
    - "system"
    - "unix"
    - "dos"
    - "!"
    - "eval"
    - "feval"
    - "evalc"
    - "evalin"
    - "assignin"
    - "perl"
    - "python"
  
  # Upload protection
  max_upload_size_mb: 100
  
  # Workspace isolation between sessions
  workspace_isolation: true
  
  # SSE-specific: acknowledge reverse proxy is in place
  require_proxy_auth: false  # Set to true for SSE deployments
  
  # Session cleanup
  session_timeout: 3600  # seconds; idle sessions expire
  temp_cleanup_on_disconnect: true

Recommended Values by Scenario

Personal/Local Development

server:
  transport: "stdio"
  
security:
  blocked_functions_enabled: true
  workspace_isolation: false  # Not needed for single user

Team Server (Intranet)

server:
  transport: "sse"
  host: "127.0.0.1"
  port: 8765
  
security:
  blocked_functions_enabled: true
  require_proxy_auth: true
  workspace_isolation: true
  session_timeout: 3600
  temp_cleanup_on_disconnect: true

Production (Internet-Facing)

server:
  transport: "sse"
  host: "127.0.0.1"
  port: 8765
  
security:
  blocked_functions_enabled: true
  blocked_functions:
    - "system"
    - "unix"
    - "dos"
    - "!"
    - "eval"
    - "feval"
    - "evalc"
    - "evalin"
    - "assignin"
    - "perl"
    - "python"
    - "web"              # Add web() if not needed
    - "urlread"          # Restrict external network access
  
  require_proxy_auth: true
  workspace_isolation: true
  session_timeout: 1800  # Shorter timeout
  temp_cleanup_on_disconnect: true
  max_upload_size_mb: 50  # Tighter limit

Customizing the Function Blocklist

To customize which functions are blocked:

  1. Identify your use case: Do you need signal processing, image processing, parallel computing, etc.?
  2. Review the default blocklist: Are there functions you legitimately need that are blocked?
  3. Update config.yaml:
security:
  blocked_functions_enabled: true
  blocked_functions:
    - "system"
    - "unix"
    - "dos"
    - "!"
    - "eval"
    - "feval"
    - "evalin"
    # Removed 'perl' and 'python' if needed for interop
    # Add custom functions you want to block
    - "my_dangerous_function"
  1. Disable entirely (not recommended):
security:
  blocked_functions_enabled: false  # All functions allowed

Best Practice: Even if you disable the blocklist, the server provides audit events for all blocked function attempts, visible in monitoring logs for security analysis.

Best Practices for Secure Deployment

Network Architecture

graph TB
    Internet["Internet / VPN"]
    
    Internet -->|TLS| ProxyLB["Load Balancer<br/>(optional)"]
    ProxyLB -->|mTLS| Proxy["Reverse Proxy<br/>with Auth<br/>(nginx/Caddy)"]
    
    Proxy -->|localhost:8765<br/>no TLS needed| Server["MATLAB MCP Server"]
    Server -->|localhost:MATLAB_PORT| MATLAB["MATLAB Engine"]
    
    Server -->|optional| Store["Metrics DB<br/>(SQLite)"]
Loading

Key Points:

  • Server listens on 127.0.0.1 (localhost only)
  • All authentication/encryption handled by reverse proxy
  • mTLS optional for proxy ↔ server connection (same machine)
  • MATLAB engine is local, not exposed to network

Session Isolation

Each authenticated user gets:

  1. Unique session ID
  2. Dedicated temporary directory
  3. Optional workspace reset (clear all) between code executions
  4. Automatic cleanup after timeout or disconnect
sessions:
  max_sessions: 10
  session_timeout: 3600  # 1 hour
  temp_cleanup_on_disconnect: true
  job_retention_seconds: 86400  # 24 hours

Monitoring and Audit Logging

Enable monitoring to track all code execution, blocked attempts, and system health:

monitoring:
  enabled: true
  db_path: "/data/metrics/matlab-mcp.db"
  sample_interval: 30  # seconds

Visit the dashboard at http://localhost:8766/dashboard to see:

  • Real-time metrics: Pool utilization, job throughput, execution times
  • Event log: All code executions, blocked attempts, errors, session creations
  • Health status: Engine pool status, memory usage, error rates

File and Process Isolation (Docker)

Deploy in Docker with volume mounts for isolation:

# docker-compose.yml
services:
  matlab-mcp:
    image: matlab-mcp:latest
    volumes:
      - ./config.yaml:/app/config.yaml:ro
      - ./custom_tools.yaml:/app/custom_tools.yaml:ro
      - matlab-data:/data  # Persistent results
      - matlab-results:/tmp/matlab-mcp-results
    networks:
      - internal
    environment:
      MATLAB_MCP_SECURITY__REQUIRE_PROXY_AUTH: "true"
      MATLAB_MCP_SECURITY__WORKSPACE_ISOLATION: "true"

  nginx:
    image: nginx:latest
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "443:443"
    networks:
      - internal
      - external

networks:
  internal:
    internal: true  # Not accessible from host
  external:
    driver: bridge

Regular Security Audits

  1. Review audit logs: Check monitoring event log for unexpected blocked attempts
  2. Rotate credentials: Update reverse proxy auth secrets regularly
  3. Update MATLAB: Keep MATLAB engine updated for security patches
  4. Monitor metrics: Watch for unusual utilization patterns or error spikes
  5. Dependency scanning: Run pip-audit to check Python dependencies for CVEs

How to Report Security Vulnerabilities

If you discover a security vulnerability, please do not open a public GitHub issue. Instead:

  1. Email: Send details to the project maintainers (check repository README for contact)

  2. Information to include:

    • Vulnerability description
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if available)
  3. Timeline: Expect acknowledgment within 48 hours; fixes typically released within 1-2 weeks

  4. Credit: You will be credited in release notes unless you prefer to remain anonymous

Responsible Disclosure

We follow responsible disclosure practices:

  • Fixes are developed in private
  • Security patch released before public disclosure
  • CVE assigned if applicable
  • Your contribution is acknowledged (with permission)

Security Features by Component

graph TB
    Request["Incoming Request"]
    
    Request -->|Proxy auth| Auth["Authentication<br/>(reverse proxy)"]
    Auth -->|Session ID| Session["Session Manager<br/>Workspace Isolation"]
    Session -->|Code + Job ID| Validator["SecurityValidator<br/>Blocklist Check"]
    Validator -->|Filename sanitize| Upload["File Upload Handler<br/>Size + Path Limits"]
    Upload -->|Workspace injected| Execute["JobExecutor<br/>Runs in isolated temp dir"]
    Execute -->|Monitor access| Monitor["Monitoring<br/>Audit Log Events"]
    Execute -->|Results| Formatter["ResultFormatter<br/>Truncate large outputs"]
    Formatter -->|Response| Response["MCP Response"]
    
    style Auth fill:#90EE90
    style Session fill:#87CEEB
    style Validator fill:#FFB6C1
    style Upload fill:#FFD700
    style Monitor fill:#DDA0DD
Loading

Summary: The MATLAB MCP Server is designed to be secure by default while remaining configurable for different threat models. Use the recommended configurations for your deployment scenario, monitor actively, and report any security issues responsibly.

Clone this wiki locally