Skip to content

security: inject X-MCP-Token on all bridge fetch sites#18

Open
D3vCrow wants to merge 1 commit intoAnkleBreaker-Studio:mainfrom
D3vCrow:security/origin-token-hardening
Open

security: inject X-MCP-Token on all bridge fetch sites#18
D3vCrow wants to merge 1 commit intoAnkleBreaker-Studio:mainfrom
D3vCrow:security/origin-token-hardening

Conversation

@D3vCrow
Copy link
Copy Markdown

@D3vCrow D3vCrow commented Apr 23, 2026

Summary

  • Load shared secret at module init from %APPDATA%/unity-mcp/secret (Windows) or $XDG_CONFIG_HOME/unity-mcp/secret (Unix)
  • Inject X-MCP-Token via new authHeaders() helper on all 6 fetch sites in src/unity-editor-bridge.js (submitToQueue, pollQueueStatus, sendCommandLegacyMode, getQueueInfo, getTicketStatus, getProjectContext)
  • Graceful degradation: if the secret file is absent, no header is sent and existing behavior is preserved — matches the plugin's EnforceToken=false default

This is the companion change to the D3vCrow fork of unity-mcp-plugin, which adds an opt-in X-MCP-Token gate on mutating verbs (POST/PUT/DELETE). Without a plugin counterpart that enforces the token, this PR is a no-op.

Test plan

  • Positive path: unity_editor_ping via MCP → connected:true, Unity 6000.3.6f1, project UnityToolkit, processId 23304
  • Bad Origin: curl -X POST -H 'Origin: http://attacker.example.com' ... → 403 {"error":"origin not allowed"}
  • Bad token: curl -X POST -H 'X-MCP-Token: wrong' ... → 403 {"error":"token invalid"}
  • Companion auto-connects to port 7891 on session restart; claude mcp list shows Connected
  • Verified against Unity plugin fork commit 3c2c67a (thread-safe snapshot) — no 'GetBool can only be called from the main thread' errors

Caveats

  • Token is cached at process start. Regenerating the secret in the plugin dashboard requires restarting the MCP server process.
  • No new dependencies — uses Node stdlib (node:fs, node:os, node:path).

Generated with Claude Code

Companion to the D3vCrow fork of unity-mcp-plugin, which adds an opt-in
X-MCP-Token gate on mutating verbs (POST/PUT/DELETE). The plugin writes
the shared secret to %APPDATA%/unity-mcp/secret on Windows or
$XDG_CONFIG_HOME/unity-mcp/secret on Unix.

unity-editor-bridge.js now loads that file once at module init and, when
present, injects X-MCP-Token alongside X-Agent-Id on every editor call
(submitToQueue, queue status poll, legacy sync POST, getQueueInfo,
getTicketStatus, getProjectContext). Missing file → no header, which is
the upstream behavior and matches the plugin's EnforceToken=false default.

A new authHeaders(extra) helper consolidates the header construction —
previously each fetch call site inlined a headers object.

Caveat: token is cached at process start. Regenerating the secret in the
dashboard requires restarting the MCP server process.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant