GitHub Advisoryadvisory · RubyGems

GHSA-5p9g-j988-pcwv MCP Ruby SDK: Ruby SSE Session Poisoning

HIGH Published 2026-07-30 Modified 2026-07-30 Official page ↗
Aliases
CVE-2026-67431
Ecosystem
RubyGems
Packages
mcp
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N
Weaknesses
CWE-284
Reviewed
2026-07-30

Affected packages

• RubyGems mcp: < 0.23.0 → fixed in 0.23.0

Description

Summary Vulnerability: Missing Session Ownership Validation in the Ruby MCP SDK's Streamable and SSE HTTP transport implementation. Any attacker with a stolen session ID can execute tools with the victim's session. This is a silent attack - the victim's session is compromised and being used for unauthorized actions, but it is hard to know for the victim Details https://github.com/modelcontextprotocol/ruby-sdk/blob/main/lib/mcp/server/transports/streamable_http_transport.rb#L260-L278 Victim starts a legitimate MCP session and receives session ID abc-123 Attacker obtains the session ID (various means - network sniffing, logs, etc. out of scope for this analysis) Attacker sends POST to /messages/abc-123 with a tool call Server accepts the request (no ownership validation!) Server executes the tool and sends response to victim's SSE stream Victim receives attacker's response, thinking it's legitimate PoC attacker_client.py legitimate_client.py Prerequisites 1. Python 3.8+ 2. Install dependencies: `requests` Running the Demo 1. Terminal 1: Start the Ruby MCP Server `ruby streamable_http_server.rb` Makes use of https://github.com/modelcontextprotocol/ruby-sdk/blob/main/examples/streamable_http_server.rb This server has a tool call notification_tool which the clients call 2. Terminal 2: Start Victim Client `python3 legitimate_client.py` 3. Terminal 3 - Attacker Client: Copy the session ID from Terminal 1 and run: ```bash python3 attacker_client.py abc-123-def-456 ``` 4. Back to Terminal 2 - Victim sees the injected response: Impact • Integrity: HIGH - Attacker can execute unauthorized tools and modify state • Availability: LOW - Attacker can disrupt victim's session with injected responses Additional Details Session Hijacking Protection in MCP Implementations The MCP specification recommends - "MCP servers SHOULD bind session IDs to user-specific information". User Binding - Comparison other SDKs csharp-sdk • https://github.com/modelcontextprotocol/csharp-sdk/blob/main/src/ModelContextProtocol.AspNetCore/SseHandler.cs#L36 • https://github.com/modelcontextprotocol/csharp-sdk/blob/main/src/ModelContextProtocol.AspNetCore/SseHandler.cs#L95-L98 Go-sdk • https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/streamable.go#L66 • https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/streamable.go#L316-L320 Comparison with the Stream Replacement vulnerability Stream Replacement https://github.com/modelcontextprotocol/ruby-sdk/security/advisories/GHSA-qvqr-5cv7-wh35 • Target: SSE stream connection • Attack Vector: GET /mcp • What happens to Victim: The connection is disconnected and doesn't receive reponses Session Poisoning • Target: Tool execution • Attack Vector: POST /mcp • What happens to Victim: The connection stays connected and receives responses of tool calls by attacker

Related

Alias · CVE (1)

  • CVE-2026-67431 MCP Ruby SDK is the official Ruby SDK for Model Context Protocol servers and clients. vulnerability

Weakness · CWE (1)

  • CWE-284 Improper Access Control weakness

References