T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- bridge.js:143
- Finding
- Unauthenticated MCP Tool Invocation and Server Restart<![CDATA[ ## Vulnerability Details **File Location**: `bridge.js:143-146, 165-190` **Vulnerability Type**: Missing authentication and authorization on privileged HTTP endpoints **Risk Level**: High ### Vulnerable Code ```js async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; } if (!checkSecurity(req, res)) return; const parts = req.url.split('/').filter(Boolean); try { if (!parts.length) { const list = {}; for (const [n, s] of servers) list[n] = s.status(); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ servers: list })); return; } const srv = servers.get(parts[0]); if (!srv) { res.writeHead(404); res.end(JSON.stringify({ error: 'Server not found' })); return; } const action = parts[1] || 'status'; if (action === 'status') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(srv.status())); } else if (action === 'tools') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ tools: srv.tools || [] })); } else if (action === 'call' && req.method === 'POST') { let body = ''; for await (const chunk of req) body += chunk; const { tool, arguments: args } = JSON.parse(body); audit(req, 'call', { server: parts[0], tool }); const result = await srv.callTool(tool, args || {}); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ result })); } else if (action === 'restart' && req.method === 'POST') { srv.stop(); srv.restarts = 0; setTimeout(() => srv.start(), 500); res.writeHead(200, { 'Content-Type': 'application/json' }); ...[truncated 2245 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Require authentication for every endpoint, using a cryptographically strong bearer token, mutual TLS, or a protected local IPC mechanism. - Apply per-server and per-tool authorization instead of granting every authenticated caller access to all MCP capabilities. - Restrict CORS to an explicit list of trusted origins. Disable CORS entirely if browser access is unnecessary. - Reject non-loopback binding unless authentication has been explicitly enabled. - Protect restart and other administrative operations with a separate administrative permission. - Consider using a Unix domain socket with restrictive filesystem permissions for local-only deployments. - Return minimal server and tool metadata to unauthenticated callers. - Add security tests confirming that unauthenticated tool calls, enumeration, and restart operations are rejected. ]]>
