Summary
The MCP Java SDK's HTTP client transports (HttpClientStreamableHttpTransport and HttpClientSseClientTransport) both parse Server-Sent Events through a shared subscriber, ResponseSubscribers.SseLineSubscriber. It accumulates every data: line into an unbounded StringBuilder and only flushes/dispatches the event on a blank line. A malicious or compromised MCP HTTP server can send an endless stream of data: lines without ever emitting the blank-line SSE terminator, causing unbounded heap growth in the client process until OOM or severe GC pressure.
Am I affected?
If your application uses HttpClientStreamableHttpTransport or HttpClientSseClientTransport (i.e. McpClient configured with the Streamable HTTP or SSE HTTP client transport) to connect to an MCP server that is untrusted, or reachable over a network path where responses can be tampered with.
Details
Multi-line data: fields are valid per the SSE spec and are intentionally concatenated before dispatch; the issue is the absence of any maximum event size or maximum line count. There is no analogue anywhere in this SDK of a frame-size cap (e.g. nothing resembling ReadBuffer.DEFAULT_MAX_FRAME_SIZE in other SDKs) applied to this buffer.
It affects both the long-lived GET event stream and the inline SSE returned on a POST response, since both paths funnel through the same subscriber.
Impact
Client-side denial-of-service (CWE-400 / CWE-770): unbounded memory use in the MCP client process until OOM or severe GC, with little CPU cost to the attacker. Any Java application using HttpClientStreamableHttpTransport or HttpClientSseClientTransport against an untrusted MCP server (or over HTTP that can be tampered with) is affected. There is no remote code execution and no direct compromise of the server.
Weaknesses
- CWE-400: Uncontrolled Resource Consumption
- CWE-770: Allocation of Resources Without Limits or Throttling
Mitigation
Upgrade to 0.18.4, 1.1.4 or 2.0.1
Summary
The MCP Java SDK's HTTP client transports (
HttpClientStreamableHttpTransportandHttpClientSseClientTransport) both parse Server-Sent Events through a shared subscriber,ResponseSubscribers.SseLineSubscriber. It accumulates everydata:line into an unboundedStringBuilderand only flushes/dispatches the event on a blank line. A malicious or compromised MCP HTTP server can send an endless stream ofdata:lines without ever emitting the blank-line SSE terminator, causing unbounded heap growth in the client process until OOM or severe GC pressure.Am I affected?
If your application uses
HttpClientStreamableHttpTransportorHttpClientSseClientTransport(i.e.McpClientconfigured with the Streamable HTTP or SSE HTTP client transport) to connect to an MCP server that is untrusted, or reachable over a network path where responses can be tampered with.Details
Multi-line
data:fields are valid per the SSE spec and are intentionally concatenated before dispatch; the issue is the absence of any maximum event size or maximum line count. There is no analogue anywhere in this SDK of a frame-size cap (e.g. nothing resemblingReadBuffer.DEFAULT_MAX_FRAME_SIZEin other SDKs) applied to this buffer.It affects both the long-lived GET event stream and the inline SSE returned on a POST response, since both paths funnel through the same subscriber.
Impact
Client-side denial-of-service (CWE-400 / CWE-770): unbounded memory use in the MCP client process until OOM or severe GC, with little CPU cost to the attacker. Any Java application using
HttpClientStreamableHttpTransportorHttpClientSseClientTransportagainst an untrusted MCP server (or over HTTP that can be tampered with) is affected. There is no remote code execution and no direct compromise of the server.Weaknesses
Mitigation
Upgrade to
0.18.4,1.1.4or2.0.1