Skip to content

Security

github-actions[bot] edited this page Apr 3, 2026 · 20 revisions
# Security

The MATLAB MCP Server includes multiple security layers to control code execution, manage authentication, and isolate user sessions while keeping MATLAB accessible to AI coding agents.

## Authentication and Authorization

### Bearer Token Authentication

When using HTTP-based transports (`streamablehttp` or legacy `sse`), the server enforces bearer token authentication to prevent unauthorized access.

```mermaid
graph LR
    A["Agent Request<br/>Authorization: Bearer token"] --> B{Token Valid?}
    B -->|Yes| C["Pass to MCP<br/>Execute tool"]
    B -->|No| D["Return 401<br/>WWW-Authenticate: Bearer"]
    E["MATLAB_MCP_AUTH_TOKEN<br/>Environment Variable"] --> B

Token Configuration

Source: Bearer token is read exclusively from the MATLAB_MCP_AUTH_TOKEN environment variable at server startup. No token should be stored in config.yaml.

Token Format: Opaque 64-character hexadecimal string (no JWT encoding required).

Bypassed Paths:

  • /health — Health check endpoint (always accessible for load balancers)
  • OPTIONS * — CORS pre-flight requests (always allowed)
  • stdio transport — No authentication (by design; local, trusted context)

Generating a Token

Use the built-in token generator:

matlab-mcp --generate-token

Output Example:

Generated bearer token:
  a7f3e2c91d4b6f8e9a0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e

Export it for your platform:

  # Linux/macOS (bash/zsh):
  export MATLAB_MCP_AUTH_TOKEN="a7f3e2c91d4b6f8e9a0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e"

  # Windows (Command Prompt):
  set MATLAB_MCP_AUTH_TOKEN=a7f3e2c91d4b6f8e9a0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e

  # Windows (PowerShell):
  $env:MATLAB_MCP_AUTH_TOKEN="a7f3e2c91d4b6f8e9a0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e"

Then start the server:
  matlab-mcp --transport streamablehttp

Agent Configuration

Agents connect by including the bearer token in the Authorization header:

# Claude Code
servers:
  matlab:
    command: "python"
    args: ["-m", "matlab_mcp", "--transport", "streamablehttp"]
    env:
      MATLAB_MCP_AUTH_TOKEN: "your_64_char_token_here"

# Codex CLI (via HTTP)
url: "http://localhost:8765/mcp"
headers:
  Authorization: "Bearer your_64_char_token_here"

Timeout-Safe Comparison: The server uses hmac.compare_digest() for constant-time token comparison, preventing timing-based token oracle attacks.

Auth Warning

The server logs a warning at startup if an HTTP-based transport is selected without the MATLAB_MCP_AUTH_TOKEN environment variable:

WARNING: No bearer token configured for HTTP transport.
  Set MATLAB_MCP_AUTH_TOKEN=<token> to enable authentication.
  Without auth, the server is vulnerable to unauthorized access.

Transport-Specific Auth

Transport Auth Enforced Bypass Paths
stdio ❌ No N/A (local, trusted)
streamablehttp ✅ Yes /health, OPTIONS
sse (deprecated) ✅ Yes /health, OPTIONS

CORS Support

When using HTTP transports, CORS headers are automatically included:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, Accept

This allows browser-based agent UIs (e.g., Cursor's web panel) to connect without CORS errors.


Input Validation and Sanitization

Code Security: Function Blocklist

The server uses smart pattern matching to detect and block dangerous MATLAB functions. By default, these functions are blocked:

Function Risk Blocked By Default
system(), unix(), dos() Execute arbitrary OS commands ✅ Yes
! (shell escape operator) Execute shell commands ✅ Yes
eval(), feval(), evalc(), evalin() Execute arbitrary code ✅ Yes
assignin() Modify caller's workspace ✅ Yes
perl(), python() Execute external scripts ✅ Yes
web() Open browser (potential exfil) ✅ Yes

Smart Detection with String/Comment Stripping

The validator strips string literals and comments before scanning, preventing false positives:

% ✅ SAFE — will NOT trigger the blocklist:
disp('system() is great')                  % "system" in string
% system('ls')                             % "system" in comment
msg = "unix-based systems";                % "unix" in string
help system                                % Harmless help call

% ❌ BLOCKED:
system('rm -rf /')                         % Actual system() call
eval(['x = ' num2str(user_input)])         % eval() with user data

Configuration

security:
  blocked_functions_enabled: true           # Set false to disable entirely (NOT recommended)
  blocked_functions:                        # Defaults shown; customize as needed
    - "system"
    - "unix"
    - "dos"
    - "!"
    - "eval"
    - "feval"
    - "evalc"
    - "evalin"
    - "assignin"
    - "perl"
    - "python"
    - "web"

Filename Validation

Filenames are sanitized to prevent path traversal and injection attacks:

Attack Example Blocked Why
Path traversal ../../etc/passwd ✅ Yes .. stripped; rejected
Absolute paths /etc/passwd ✅ Yes / disallowed
Special chars file;rm -rf / ✅ Yes Only [a-zA-Z0-9._-] allowed
Unicode tricks файл.m ✅ Yes ASCII only

Allowed Characters: Letters, digits, dots (.), underscores (_), hyphens (-)

Example Validations

% ✅ ACCEPTED:
read_script("signal_analysis.m")
upload_data("train_data_v2.csv")
read_image("plot_2024-01-15.png")

% ❌ REJECTED:
read_script("../../etc/passwd")             % Path traversal
upload_data("/tmp/malicious.mat")           % Absolute path
delete_file("data;rm -rf /")                % Shell injection attempt

File Operations

All file operations are scoped to the session's temporary working directory:

execution:
  workspace_isolation: true           # Enable session-scoped temp dirs (default: true)
  max_upload_size_mb: 100             # Reject uploads exceeding this size

Configuration Security

Sensitive Key Detection

The server warns if sensitive keys appear in config.yaml at startup:

# ❌ DON'T DO THIS (will trigger warning):
security:
  auth_token: "a7f3e2c91d4b6f8e9a0c1d2e3f4a5b6c"  # Warning: token in config!

# ✅ DO THIS (no warning):
# Set MATLAB_MCP_AUTH_TOKEN environment variable instead

Startup Warning Example:

WARNING: Sensitive keys detected in config.yaml:
  - auth_token
  
These should NOT be stored in config files. Use environment variables instead:
  export MATLAB_MCP_AUTH_TOKEN="..."

Environment Variable Precedence

All configuration values support MATLAB_MCP_* environment variable overrides, which take precedence over config.yaml:

# Override from command line
export MATLAB_MCP_AUTH_TOKEN="your_token"
export MATLAB_MCP_SERVER_TRANSPORT="streamablehttp"
export MATLAB_MCP_SECURITY_BLOCKED_FUNCTIONS_ENABLED="true"

# Then start the server (config.yaml values are overridden)
matlab-mcp --config my_config.yaml

Human-in-the-Loop Approval Gates

When enabled, certain operations pause and request human approval via the MCP elicitation protocol before executing.

Configuration

hitl:
  enabled: false                            # Master switch (default: disabled)
  protected_functions:                      # Functions requiring approval when called
    - "fopen"
    - "delete"
  protect_file_ops: false                   # Require approval for upload/delete?
  all_execute: false                        # Require approval for ALL code execution?

Supported Gates

Operation Enabled By Example Flow
Protected function execution hitl.enabled: true + function in protected_functions Code calls delete() → server pauses → requests approval → resumes on "accept"
File upload/delete hitl.protect_file_ops: true Agent calls upload_data() → server pauses → human reviews filename/size → approves or denies
All code execution hitl.all_execute: true Any execute_code call → server pauses → human reviews code → approves or denies

Example Usage

% Config: hitl.protected_functions = ["delete"]
delete('old_file.txt')                % ⏸ Paused: "Approve deletion of old_file.txt?"
                                      % Human clicks "approve" in client UI
                                      % ✅ Execution resumes; file deleted

Approval Responses

Agents (or humans in the loop) can:

  • Accept — Proceed with the operation
  • Decline — Deny the operation; return error to agent
  • Cancel — Cancel the operation without error

Session Isolation

Workspace Isolation

Each session gets its own isolated MATLAB workspace. Sessions don't share:

  • Variables
  • Functions (beyond built-in)
  • File handles
  • Current directory
  • Path (toolbox paths)
execution:
  workspace_isolation: true           # Clear workspace between tool calls (default: true)

When workspace_isolation: true, the server runs at the start of each session:

clear all
clear global
clear functions
fclose all
restoredefaultpath

Temporary Directory Isolation

Each session has its own temporary working directory:

/tmp/matlab_mcp_sessions/
├── session_abc123/                # User A
│   ├── upload1.mat
│   ├── results.csv
│   └── ...
├── session_def456/                # User B
│   ├── data.xlsx
│   └── ...
└── ...

Files uploaded by one user are not visible to another. When a session times out or is destroyed, its temp directory is deleted.

Configuration

sessions:
  max_sessions: 10                        # Maximum concurrent sessions
  session_timeout_seconds: 3600           # Idle timeout (1 hour default)
  job_retention_seconds: 86400            # Keep job history 24 hours
  temp_cleanup_on_disconnect: true        # Delete temp files on session end (default: true)

Monitoring and Audit Logging

Event Logging

The server logs security-relevant events to stdout/file:

Event Type Logged Example
Blocked function detected ✅ Yes SECURITY: Blocked 'system()' call in code
Invalid auth token ✅ Yes AUTH: Invalid bearer token from 127.0.0.1
File path traversal attempt ✅ Yes SECURITY: Path traversal rejected: ../../etc/passwd
Session timeout ✅ Yes SESSION: Closed session session_abc123 (idle 1h)
HITL approval event ✅ Yes HITL: Approved execution of protected function delete()

Health Check Endpoint

The /health endpoint exposes server status without authentication:

curl http://localhost:8765/health

Response:

{
  "status": "healthy",
  "uptime_seconds": 3600,
  "active_jobs": 2,
  "active_sessions": 3,
  "engine_pool": {"available": 5, "busy": 3, "total": 8},
  "error_rate_percent": 0.5
}

Metrics and Dashboard

The /dashboard endpoint (HTTP transport only) provides real-time metrics:

http://localhost:8765/dashboard

Tracks:

  • Engine pool utilization
  • Job throughput and latency
  • Error rates and failure types
  • Session activity
  • System resource usage

Deployment Security Recommendations

Personal Use (Single Agent)

server:
  transport: "stdio"              # Local only; no auth needed
  
security:
  blocked_functions_enabled: true # Keep default blocklist
  workspace_isolation: true

Security Posture: ✅ Low risk (trusted local agent only)


Team Server (Multi-User)

server:
  transport: "streamablehttp"
  host: "127.0.0.1"               # Bind to localhost
  port: 8765
  
security:
  blocked_functions_enabled: true
  workspace_isolation: true

sessions:
  max_sessions: 5
  session_timeout_seconds: 3600

hitl:
  enabled: true                   # Require approval for sensitive ops
  protected_functions:
    - "delete"
    - "fopen"
  protect_file_ops: true

Setup:

  1. Generate a token: matlab-mcp --generate-token
  2. Export to all team members: export MATLAB_MCP_AUTH_TOKEN="..."
  3. Each agent/IDE configures the token in their MCP client settings
  4. Server logs all operations for audit trail

Security Posture: ✅ Medium (auth + workspace isolation + approval gates)


Production Deployment (Corporate/Public)

server:
  transport: "streamablehttp"
  host: "0.0.0.0"                 # Exposed via reverse proxy below
  port: 8765
  stateless_http: true            # No session affinity (load-balanced)
  
security:
  blocked_functions_enabled: true
  workspace_isolation: true
  max_upload_size_mb: 50          # Tighter limits
  
sessions:
  max_sessions: 100
  session_timeout_seconds: 1800   # 30 min (shorter for shared infra)
  
hitl:
  enabled: true
  protected_functions:
    - "delete"
    - "fopen"
    - "system"                    # Even if not blocked, require approval
    - "evalin"
  protect_file_ops: true
  all_execute: false              # Set true if you want to review ALL code

Required Reverse Proxy Setup (nginx example):

server {
    listen 443 ssl http2;
    server_name matlab-mcp.company.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    
    # Authentication at reverse proxy level
    auth_request /oauth2/auth;
    error_page 401 = /oauth2/sign_in;
    
    location / {
        proxy_pass http://127.0.0.1:8765;
        proxy_set_header Authorization $http_authorization;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

Security Posture: ✅ High (TLS + reverse proxy auth + bearer tokens + workspace isolation + approval gates + audit logging)


Reporting Security Vulnerabilities

If you discover a security vulnerability in the MATLAB MCP Server:

  1. Do NOT open a public GitHub issue — this discloses the vulnerability to attackers
  2. Email security details to: [project maintainer or security contact]
  3. Include:
    • Description of the vulnerability
    • Steps to reproduce
    • Potential impact
    • Any suggested fixes

The maintainers will acknowledge receipt within 48 hours and work with you on a fix. Coordinated disclosure timelines typically allow 90 days before public disclosure.


Known Limitations and Caveats

SSE Transport (Deprecated)

The legacy SSE transport is deprecated in v2.0 and will be removed in v3.0. It has inherent security limitations:

  • Requires a reverse proxy with authentication (no built-in auth)
  • Cannot enforce TLS without a proxy
  • Session cookies are fragile over long-lived connections

Migration Path: Use streamablehttp transport instead (see Configuration).

Code Sanitization (Best-Effort)

The security validator uses regex-based pattern matching to detect blocked functions. While it handles most common cases (including string/comment stripping), it is not a formal AST-based code parser. Sophisticated obfuscation might evade detection.

Recommendation: If security is critical, run the server on a restricted-access machine or behind a proxy that enforces additional application-level controls.

MATLAB Function Scope

The blocklist covers the most dangerous MATLAB functions, but new threats may emerge. Regularly review and update config.yaml as needed.

Custom Blocklist Example:

security:
  blocked_functions:
    - "system"
    - "unix"
    - "dos"
    - "!"
    - "eval"
    - "feval"
    - "evalc"
    - "evalin"
    - "assignin"
    - "perl"
    - "python"
    - "web"
    - "importdata"        # Add your own here
    - "xlsread"           # e.g., if your org forbids certain functions

References

Clone this wiki locally