fix(mcp): warn when MCPServer starts without authentication#3044
fix(mcp): warn when MCPServer starts without authentication#3044failsafesecurity wants to merge 1 commit into
Conversation
When security=None (the default), the MCP HTTP endpoint serves without any authentication middleware — any network client can invoke the agent's tools without credentials. Emit a UserWarning and a log warning at construction time so deployers are aware of the risk. This is not a breaking change; the default behavior is unchanged, just loudly warned. Refs: AGNT-001
|
Joshua Medvinsky seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
@failsafesecurity, thanks for the contribution! Can you please re-instate the PR template? |
|
Hi @failsafesecurity, thanks for the contribution! Before we can review or merge this PR, you need to sign our Contributor License Agreement — the Once the CLA is signed, the check turns green, the ⏳ If the CLA isn't signed within 3 days, this PR will be marked stale and closed 7 days after that. Signing later and reopening is always an option. |
genisis0x
left a comment
There was a problem hiding this comment.
Real gap to close — with security=None as the default, the streamable HTTP endpoint serves shell/code/web-fetch tools with no auth, and that's easy to ship by accident. Surfacing it at construction time is the right call.
Two small things:
- The
_logger = logging.getLogger(__name__)line lands between the stdlib imports and thefrom mcp.server.auth...imports. A module-level statement sitting mid-import-block is the kind of thing ruff/isort flags (E402) and it reads a bit oddly — worth moving_loggerdown below all the imports. - Emitting both a
warnings.warn(UserWarning)and a_logger.warning(...)for the same condition is a little redundant. For a construction-time misconfiguration theUserWarningis the natural channel (dev-visible, and the warnings filter dedupes it); the log line mostly duplicates it. Keeping one would be cleaner.
Is there a test pinning that the warning fires on security=None and stays silent when a Requirement is passed?
Summary
When
security=None(the default), the MCP HTTP endpoint serves without any authentication middleware — any network client can invoke the agent's tools (shell, code execution, web fetch) without credentials.This PR emits a
UserWarningand alogging.warningat construction time so deployers are aware of the risk. The default behavior is unchanged — this is not a breaking change, just a loud warning.Security Impact
High — An exposed MCP server with default settings allows unauthenticated tool invocation. Combined with prompt injection, this enables:
Changes
warnings.warn()+logging.warning()inMCPServer.__init__whensecurity is NoneloggingandwarningsmodulesTesting
Exploit Chain
Unauthenticated MCP client → prompt injection → agent executes shell command or fetches cloud metadata. See [CHAIN-001] in our analysis.
Remediation Options (for future PRs)
securitya required parameter (breaking change)Requirementwith API key from env var