
Bind authenticated identity to sessions in StreamableHTTPSessionManager
快速结论:该安全问题发生在 MCP Python SDK 的 StreamableHTTPSessionManager 中,当启用身份认证(Auth)时,Session 管理器仅依赖 Mcp-Session-Id 头路由请求,未验证当前请求的认证身份是否与创建该 Session 的身份一致。优先排查 SDK 版本是否升级到 v1.27.2(v1.x 分支)或 main 分支最新提交 #2718。
问题场景
用户使用 MCP Python SDK 构建 HTTP 服务端,启用了 Bearer 令牌认证(如 BearerAuthBackend / RequireAuthMiddleware),且使用了 StreamableHTTPSessionManager 管理有状态会话。当多个用户共享同一 Session ID(例如日志泄露、非 TLS 网络窃听、共享基础设施)时,可能发生身份冒充。
报错原文
StreamableHTTPSessionManager._handle_stateful_request routes incoming requests to existing sessions based solely on the Mcp-Session-Id header value. There is no check that the authenticated identity on the incoming request matches the identity that originally created the session.
原因分析
认证中间件(Auth Middleware)与会话路由(Session Manager)是解耦的两层:认证层验证令牌并将认证上下文存储在 contextvar 中;而 Session 管理器仅通过 Mcp-Session-Id 头进行字典查找。两者从不交叉验证,导致泄露的 Session ID 可被任意持有者使用,绕过新增的身份认证。
环境排查
- MCP Python SDK 版本:确认当前版本(v1.x 分支需要 ≥ v1.27.2;v2 分支需要包含 #2718 的版本)
- 认证中间件:是否启用了
BearerAuthBackend/RequireAuthMiddleware等认证组件 - Session 管理器类型:是否使用了
StreamableHTTPSessionManager(有状态会话模式)
解决步骤
- 升级 MCP Python SDK:
- v1.x 分支:升级到 v1.27.2 或更高版本(包含 PR #2719,基于 #2690 新增的 AccessToken subject/claims 功能)
- main 分支(v2):合并 PR #2718 的提交
- 升级后,
StreamableHTTPSessionManager在创建 Session 时会自动记录认证主体(client_id、令牌签发者/主题),并在每次请求时将其与当前请求的认证身份比对,身份不匹配时返回 404 “Session not found”(与未找到 Session 的错误一致,避免信息泄露)。 - 该绑定逻辑也同时应用于 SSE(Server-Sent Events)传输层。
验证方法
更新后,使用不同认证身份的令牌(不同 client_id 或不同 subject)访问同一 Session ID:应当收到 404 响应,无法访问原会话资源。同时检查日志确认后端记录的身份比对过程正常。
![[Bug]Docker 镜像更新问题及实时对话无法使用的错误问题](https://www.chat-gpts.plus/wp-content/uploads/2026/06/6264-459bd35e-768x403.jpg)
![[Bug] cloudflare部署时无法访问华为云](https://www.chat-gpts.plus/wp-content/uploads/2026/06/6611-08b1ee3a-768x403.jpg)
