The Ruby SDK's streamable_http_transport.rb implementation contains a session hijacking vulnerability. An attacker who obtains a valid session ID can completely hijack the victim's Server-Sent Events (SSE) stream and intercept all real-time data.
Root Cause The StreamableHTTPTransport implementation stores only one SSE stream object per session ID and lacks:
File: streamable_http_transport.rb - L336-L339:
def store_stream_for_session(session_id, stream)
@mutex.synchronize do
if @sessions[session_id]
@sessions[session_id][:stream] = stream # OVERWRITES existing stream
else
stream.close
end
end
end
Step 1: Legitimate Session Establishment
POST / (initialize) → receives session_id: "abc123"
GET / with Mcp-Session-Id: abc123 → SSE stream connected
Step 2: Session ID Compromise
Step 3: Stream Hijacking
GET / with Mcp-Session-Id: abc123
@sessions["abc123"][:stream] = attacker_stream `# Victim's stream is REPLACED (silently disconnected)
Step 4: Data Interception
The vulnerability happens:
Client 1 connects (GET request)
proc do |stream1| # ← Rack server provides stream1 for client 1
@sessions[session_id][:stream] = stream1 # Stored
end
```...
0.9.2Exploitability
AV:NAC:LAT:PPR:NUI:NVulnerable System
VC:HVI:NVA:NSubsequent System
SC:NSI:NSA:N8.2/CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N