Skip to content

Security: WebSocket server binds to 0.0.0.0 instead of localhost #158

@robcohen

Description

@robcohen

Summary

The WebSocket server binds to all network interfaces (0.0.0.0:9009) instead of localhost (127.0.0.1:9009), allowing anyone on the local network to send browser control commands.

Impact

On shared networks (coffee shops, offices, hotels), an attacker on the same network can:

  • Navigate the browser to arbitrary URLs
  • Click elements, type text, take screenshots
  • Read page content via snapshots
  • Execute any browser automation command

Reproduction

# Start the MCP server
npx @browsermcp/mcp@latest

# On the same machine or any machine on the local network:
ss -tlnp | grep 9009
# Shows: LISTEN *:9009  (bound to all interfaces)

Root Cause

In src/ws.ts:

async function createWebSocketServer(port = mcpConfig.defaultWsPort) {
  // ...
  return new WebSocketServer({ port });  // No host parameter
}

The ws library defaults to 0.0.0.0 when no host is specified.

Suggested Fix

return new WebSocketServer({ port, host: '127.0.0.1' });

Or better, add a --host flag with secure default:

program
  .option('--host <host>', 'Host to bind to', '127.0.0.1')
  .option('--port <port>', 'Port to bind to', '9009')

Comparison

Other MCP servers handle this correctly:

  • @playwright/mcp - binds to localhost by default
  • browserbase/mcp-server-browserbase - has --host flag, defaults to localhost

Environment

  • Package: @browsermcp/mcp@0.1.3
  • OS: Linux (also affects Windows/macOS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions