# Security Considerations When Running Untrusted Handlers in Unity MCP: Architecture and Mitigations

> Learn Unity MCP security risks from untrusted handlers. Discover architecture vulnerabilities and mitigation strategies to prevent code execution and network threats.

- Repository: [いすず/unitymcp](https://github.com/isuzu-shiranui/unitymcp)
- Tags: security
- Published: 2026-03-04

---

**Unity MCP executes dynamically discovered handlers via reflection on Unity's main thread without sandboxing, exposing projects to arbitrary code execution, denial-of-service attacks, and network-based threats when loading untrusted assemblies.**

Unity MCP (Message Command Protocol) enables extensible command handling through the `isuzu-shiranui/unitymcp` repository's reflection-based discovery system. While this architecture provides powerful flexibility for editor automation, it simultaneously creates a substantial attack surface when executing handlers from unverified third-party assemblies.

## How Unity MCP Discovers and Executes Handlers

Understanding the handler lifecycle is essential for evaluating security risks. The system discovers, instantiates, and executes handlers through several tightly coupled stages defined in the core server implementation.

### Reflection-Based Discovery in McpHandlerDiscovery.cs

The discovery process begins in [`McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpHandlerDiscovery.cs) at lines 34-55, where the system scans every loaded assembly in the current AppDomain:

```csharp
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var handlerTypes = assembly.GetTypes().Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);

```

This reflection-based approach identifies any non-abstract type implementing `IMcpCommandHandler` or `IMcpResourceHandler`, regardless of the assembly's origin or trust status. The code explicitly excludes only core Unity and System assemblies, leaving all third-party packages and dynamically loaded DLLs eligible for handler registration.

### Handler Instantiation and Registration

Once discovered, handlers are instantiated via `Activator.CreateInstance` and registered with the server. In [`McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpHandlerDiscovery.cs) lines 61-66, the system creates instances without constructor arguments:

```csharp
var instance = (T)Activator.CreateInstance(handlerType);
this.registerAction(instance);

```

The registration callback stores handlers in [`McpServer.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpServer.cs) (lines 85-115) within a dictionary keyed by command prefix:

```csharp
this.commandHandlers[commandPrefix] = new HandlerRegistration(handler, enabled);

```

This registration persists the handler's enabled state in `McpSettings`, but performs no cryptographic verification or signature checking on the assembly source.

### Synchronous Execution on the Main Thread

Command execution occurs in [`McpServer.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpServer.cs) lines 100-150 via the `ExecuteCommand` method, which queues actions to run exclusively on Unity's main thread:

```csharp
ExecuteOnMainThread(() => {
    result = registration.Handler.Execute(action, parameters);
});

```

The system implements a 5-second timeout via `waitHandle.WaitOne(5000)`, but the handler still executes synchronously on the main thread, blocking the Unity Editor UI during operation.

## Critical Security Risks When Running Untrusted Handlers

The architectural design of Unity MCP creates several vulnerability classes when executing code from untrusted sources.

### Arbitrary Code Execution via Assembly Loading

Because [`McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpHandlerDiscovery.cs) scans all loaded assemblies without whitelist validation, any malicious DLL placed in the project can implement `IMcpCommandHandler` and gain full access to the Unity Editor API. Attackers can leverage `EditorApplication`, `AssetDatabase`, `File.IO`, and network classes to execute destructive operations. The [`CodeExecutionCommandHandler.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/CodeExecutionCommandHandler.cs) sample demonstrates this risk explicitly, showing how handlers can execute arbitrary C# code within the editor context.

### Lack of Sandboxing and Isolation

Handlers execute within the same AppDomain and process as the Unity Editor, sharing memory space and security context. Unlike sandboxed plugin architectures that use separate processes or restricted AppDomains, Unity MCP provides no isolation boundary. A malfunctioning or malicious handler can directly corrupt scene files, delete assets from the `AssetDatabase`, or modify editor preferences stored in the registry.

### Denial-of-Service via Main Thread Blocking

The synchronous execution model in `ExecuteCommand` creates a denial-of-service vulnerability. Because handlers run on the main Unity thread via `ExecuteOnMainThread`, a long-running computation or infinite loop within a handler will freeze the Unity Editor UI. While the 5-second timeout (`waitHandle.WaitOne(5000)`) eventually triggers, the main thread remains blocked during execution, potentially causing editor instability or data loss from unsaved changes.

### Unauthorized Network Access via UDP Discovery

The UDP discovery mechanism in [`McpServer.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpServer.cs) lines 331-376 accepts broadcast packets from any network source without authentication:

```csharp
switch (messageType) {
    case "mcp_server_announce":
        this.TryConnect();
        break;
}

```

This allows malicious hosts to announce fake MCP servers, potentially causing the Unity client to connect to attacker-controlled endpoints. Once connected, the client may expose project information including the client ID, Unity version, and hashed project paths, or receive crafted JSON commands designed to exploit handler vulnerabilities.

### Input Validation Vulnerabilities

The command parsing logic in `ExecuteCommand` (lines 128-139) splits command strings on the `.` character with minimal validation:

```csharp
var parts = command.Split('.');
if (parts.Length < 2) {
    return ErrorResult("Invalid command format");
}

```

Malformed commands or excessively long strings may trigger exception handling paths that reveal internal state information. While the system catches exceptions to prevent crashes, error messages may leak sensitive configuration details to potential attackers.

### Sensitive Data Exposure via Logging

When `McpSettings.detailedLogs` is enabled, the system logs complete JSON command payloads and responses to the Unity console. If commands contain authentication tokens, file paths, or proprietary parameters, these details persist in log files. An attacker with read access to Unity editor logs or the console window could extract these sensitive values from the detailed debug output.

## Mitigation Strategies for Secure Handler Execution

Implementing defensive measures requires modifying the discovery, execution, and networking layers of the Unity MCP architecture.

### Implementing Assembly Whitelists

Restrict handler discovery to explicitly trusted assemblies by modifying [`McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpHandlerDiscovery.cs):

```csharp
// In DiscoverAndRegister()
var whitelist = new[] { "UnityMCP", "MyTrustedPackage", "VerifiedVendor" };
if (!whitelist.Any(prefix => assembly.FullName.StartsWith(prefix)))
{
    continue; // Skip unknown assemblies
}

```

This prevents third-party packages from registering handlers without explicit inclusion in the whitelist.

### Enforcing Execution Timeouts

Wrap handler execution in a cancellable task to prevent main thread blocking:

```csharp
private JObject RunHandlerSafely(IMcpCommandHandler handler, string action, JObject parameters)
{
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
    var task = Task.Run(() => handler.Execute(action, parameters), cts.Token);
    try { return task.Result; }
    catch (OperationCanceledException) { 
        return ErrorResult("Handler execution timeout"); 
    }
}

```

This pattern limits execution time and prevents infinite loops from hanging the Unity Editor.

### Securing UDP Discovery

Add authentication token validation to the `ReceiveCallback` method in [`McpServer.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpServer.cs):

```csharp
// In ReceiveCallback
var token = serverInfo["authToken"]?.ToString();
if (token != ExpectedAuthToken) { 
    return; // Ignore unauthenticated announcements
}
this.TryConnect();

```

Only servers presenting the pre-shared secret can trigger automatic connections.

### Sanitizing Debug Output

Prevent sensitive data leakage by filtering detailed logs:

```csharp
private bool DetailedLogs => McpSettings.instance.detailedLogs && !IsSensitiveCommand(prefix);

private bool IsSensitiveCommand(string prefix)
{
    var sensitivePrefixes = new[] { "auth", "credentials", "private" };
    return sensitivePrefixes.Any(p => prefix.Contains(p));
}

```

This ensures commands containing authentication or credential data never appear in console logs.

### Explicit Handler Disabling

Maintain a disable list in `McpSettings` to block specific handlers:

```csharp
public HashSet<string> disabledPrefixes = new HashSet<string> { "UntrustedVendor", "SuspiciousPackage" };

```

Check this collection during registration to prevent known problematic handlers from activating, even if present in loaded assemblies.

## Summary

- **Unity MCP loads handlers via reflection** from all assemblies in the AppDomain without signature verification, as implemented in [`McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpHandlerDiscovery.cs).
- **Handlers execute synchronously on the main thread** with full Unity API access, creating risks of UI freezing and arbitrary code execution.
- **No sandboxing exists** between handlers and the Unity Editor, allowing direct access to project assets and editor state.
- **UDP discovery accepts unauthenticated broadcasts**, enabling potential man-in-the-middle or spoofing attacks.
- **Mitigation requires implementing assembly whitelists**, execution timeouts, UDP authentication, and sensitive data filtering to secure the MCP environment.

## Frequently Asked Questions

### How does Unity MCP discover handlers without authentication?

Unity MCP uses reflection in [`McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpHandlerDiscovery.cs) (lines 34-55) to scan `AppDomain.CurrentDomain.GetAssemblies()` for types implementing `IMcpCommandHandler`. The system instantiates eligible types via `Activator.CreateInstance` without verifying assembly signatures or publisher identities, allowing any loaded DLL to register handlers automatically.

### Can a malicious handler delete project assets or crash the Unity Editor?

Yes. Because handlers execute in the same AppDomain as the Unity Editor with full API access, malicious code can invoke `AssetDatabase.DeleteAsset()`, modify scene files, or enter infinite loops that block the main thread. The synchronous execution model in `McpServer.ExecuteCommand` provides no isolation from the editor process.

### What timeout exists for handler execution?

The `ExecuteCommand` method in [`McpServer.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/McpServer.cs) implements a 5-second timeout using `waitHandle.WaitOne(5000)`. However, this only affects the waiting mechanism; the handler itself runs synchronously on the main thread via `ExecuteOnMainThread`, meaning long-running operations will freeze the Unity UI until completion or timeout.

### How can I prevent specific packages from registering MCP handlers?

Implement an assembly whitelist in `McpHandlerDiscovery.DiscoverAndRegister()` that checks `assembly.FullName` against trusted prefixes before instantiating handlers. Alternatively, maintain a `disabledPrefixes` HashSet in `McpSettings` and check it during the registration callback to block specific vendor prefixes from activating.