Skip to content

security(mcp): refuse standalone MCP binding on 0.0.0.0 / :: / *#2197

Open
axin8999-droid wants to merge 1 commit intoflipped-aurora:mainfrom
axin8999-droid:feat/mcp-security-guard
Open

security(mcp): refuse standalone MCP binding on 0.0.0.0 / :: / *#2197
axin8999-droid wants to merge 1 commit intoflipped-aurora:mainfrom
axin8999-droid:feat/mcp-security-guard

Conversation

@axin8999-droid
Copy link
Copy Markdown

The standalone cmd/mcp binary currently binds with fmt.Sprintf(":%d", Addr), which on Linux and Docker is equivalent to listening on every interface (0.0.0.0 + ::). The MCP endpoint exposes code-generation, DB-execution and menu/API mutation tools; exposing it to any routable network effectively hands out RCE to whoever can reach the port.

This patch makes the safe default explicit:

  • config.MCP.ListenHost: new optional field. Empty defaults to "127.0.0.1".
  • cmd/mcp/config.go: applyStandaloneDefaults fills the loopback default so an operator who forgets to configure the field never accidentally opens the port to the world.
  • cmd/mcp/main.go: refuses to start when listen_host resolves to 0.0.0.0, :: or *, with a panic message pointing to the safer fix (loopback or a specific private interface + reverse proxy).
  • cmd/mcp/config.yaml: documents the new field with the recommended 127.0.0.1 default.

Startup bind address is now built via net.JoinHostPort, which also makes IPv6 literal hosts (e.g. [::1]) work correctly.

No functional change when the existing base_url: http://127.0.0.1:8889/mcp convention is followed. The only behavioral regression is for deployments that actively relied on global-interface exposure, which this patch argues should never have been the default.
“发现 MCP 存在 O.O.O.O 绑定风险,特此修复。”“使用 AI 辅助生成”

The standalone `cmd/mcp` binary currently binds with `fmt.Sprintf(":%d", Addr)`,
which on Linux and Docker is equivalent to listening on every interface
(0.0.0.0 + ::). The MCP endpoint exposes code-generation, DB-execution and
menu/API mutation tools; exposing it to any routable network effectively
hands out RCE to whoever can reach the port.

This patch makes the safe default explicit:

- `config.MCP.ListenHost`: new optional field. Empty defaults to "127.0.0.1".
- `cmd/mcp/config.go`: `applyStandaloneDefaults` fills the loopback default so
  an operator who forgets to configure the field never accidentally opens
  the port to the world.
- `cmd/mcp/main.go`: refuses to start when `listen_host` resolves to
  `0.0.0.0`, `::` or `*`, with a panic message pointing to the safer fix
  (loopback or a specific private interface + reverse proxy).
- `cmd/mcp/config.yaml`: documents the new field with the recommended
  127.0.0.1 default.

Startup bind address is now built via `net.JoinHostPort`, which also makes
IPv6 literal hosts (e.g. `[::1]`) work correctly.

No functional change when the existing `base_url: http://127.0.0.1:8889/mcp`
convention is followed. The only behavioral regression is for deployments
that actively relied on global-interface exposure, which this patch argues
should never have been the default.

Made-with: Cursor
@pixelmaxQm
Copy link
Copy Markdown
Collaborator

@copilot 这个pr中存在较多ai注释 剔除掉ai注释

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.

2 participants