You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Truncate untrusted peer-controlled values before logging/raising
Follow-up to 3041fd0 which truncated a client-controlled session ID.
A sweep of the codebase found ~30 more locations where values controlled
by the other side of the connection are interpolated unbounded into log
messages, exception messages, or HTTP error responses.
Server-side (client-controlled input):
- sse.py: session_id query param (direct analog of 3041fd0)
- transport_security.py: Host/Origin headers at WARNING
- mcpserver: tool names, prompt names, resource URIs in 'Unknown X'
errors and logger.exception calls
- streamable_http.py: mcp-protocol-version header echoed in 400 body
- auth handlers: client_id, scope, redirect_uri echoed in error responses
- task handlers: task_id, pagination cursor in error messages
Client-side (server-controlled input):
- streamable_http.py: mcp-session-id response header, content-type
header, raw InitializeResult dict
- session.py: protocol_version from InitializeResult
- session_group.py: MCPError str (= server's error.message verbatim)
- sse.py/streamable_http.py: SSE event names
Protocol-level (shared/session.py):
- error.message from null-ID JSONRPCError
- Response ID in 'cannot be normalized' warning
- Unknown-request-ID error: was logging entire SessionMessage repr
(full wire payload), now logs just the truncated ID
- Dropped full JSONRPCNotification repr from validation-failure warning
Also removed three debug logs in server/sse.py that stringified the full
request body / parsed message on every POST via eager f-string evaluation.
Truncation lengths: 32 for version strings, 64 for IDs/tokens, 128 for
names/headers, 256 for URIs/messages, 512 for result dicts.
0 commit comments