ruby-sdk/test/mcp
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Koichi ITO 267b8fa628 Bound stdio frame reads with max_line_bytes
## Motivation and Context

CRuby's `IO#gets` without a limit reads until the next newline with no upper bound.
A peer that never emits a newline can therefore grow a single String until the process
is killed by the OS OOM killer.

This is a denial-of-service exposure (GHSA-7683-3w9x-ch42), identified during
a cross-SDK audit of the same unbounded-buffer pattern across the MCP SDKs.
It is most relevant when a host application spawns a sandboxed or untrusted MCP server
and pipes its stdout into an unconstrained host process, where a memory-capped peer
can exhaust the host.

Each frame is now capped at a configurable `max_line_bytes` (default 4 MiB,
large enough for any realistic frame including base64-embedded images,
and the value recommended in the advisory). A frame that reaches the limit without
a newline is treated as a transport error: the client raises, and the server reports
the error and closes the connection. A short final frame that ends at EOF without
a trailing newline is still accepted, so legitimate traffic is unaffected.

Both constructors validate `max_line_bytes:` as a positive Integer,
since `nil` or a non-positive value makes `IO#gets` read without an upper bound and
would silently disable the protection.

## How Has This Been Tested?

Server tests cover the `open` read loop stopping and reporting on an over-limit frame,
the `send_request` read loop raising on an over-limit response, and a valid final frame
without a trailing newline still being processed.

Client tests cover `read_response` raising on an over-limit response frame and
a normal response still round-tripping within a custom `max_line_bytes`.

Both transports also have tests rejecting invalid `max_line_bytes:` values
(`nil`, zero, negative, non-Integer) with an `ArgumentError`.

The full test suite and RuboCop pass.

## Breaking Changes

None. The default 4 MiB limit is far larger than any realistic JSON-RPC frame,
so existing well-behaved traffic is unaffected. The new `max_line_bytes:` keyword
on both transport constructors is purely additive and optional.
2026-07-05 21:30:28 +09:00
..
client Bound stdio frame reads with max_line_bytes 2026-07-05 21:30:28 +09:00
prompt Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
resource Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
server Bound stdio frame reads with max_line_bytes 2026-07-05 21:30:28 +09:00
tool Conform Tool Schemas to JSON Schema 2020-12 per SEP-2106 2026-06-19 21:36:55 +09:00
annotations_test.rb Add audience role validation for MCP::Annotations per MCP specification 2026-06-22 01:13:17 +09:00
cancellation_test.rb Support notifications/cancelled per MCP specification 2026-05-03 04:02:22 +09:00
client_test.rb Support client-side notifications/cancelled per MCP specification 2026-06-23 12:39:53 +09:00
configuration_test.rb feat: add opt-in tool output validation 2026-05-12 16:20:43 -04:00
content_test.rb Add _meta field to resource, content, and result classes 2026-04-11 15:08:55 +09:00
icon_test.rb Replace assert_empty with assert_equal using explicit literals 2026-02-24 16:09:34 +09:00
instrumentation_test.rb Add around_request hook for request instrumentation 2026-04-11 13:54:47 +09:00
logging_message_notification_test.rb Add logging support 2026-01-26 22:23:46 +09:00
methods_test.rb Add roots/list and notifications/roots/list_changed support 2026-04-15 02:39:14 +09:00
progress_test.rb Auto-set server.transport in Transport#initialize 2026-04-09 12:08:55 +09:00
prompt_test.rb Fix Prompt#validate_arguments! crash when arguments are nil 2026-03-01 17:21:41 +09:00
resource_template_test.rb Add annotations field to MCP::Resource and MCP::ResourceTemplate per MCP specification 2026-06-14 16:05:25 +09:00
resource_test.rb Add annotations field to MCP::Resource and MCP::ResourceTemplate per MCP specification 2026-06-14 16:05:25 +09:00
server_cancellation_test.rb Support client-side notifications/cancelled per MCP specification 2026-06-23 12:39:53 +09:00
server_context_test.rb Fix a SyntaxError on Ruby 2.7.0 caused by arguments forwarding syntax 2026-06-20 01:01:07 +09:00
server_elicitation_test.rb Support notifications/cancelled per MCP specification 2026-05-03 04:02:22 +09:00
server_notification_test.rb Auto-set server.transport in Transport#initialize 2026-04-09 12:08:55 +09:00
server_progress_test.rb Auto-set server.transport in Transport#initialize 2026-04-09 12:08:55 +09:00
server_roots_test.rb Add roots/list and notifications/roots/list_changed support 2026-04-15 02:39:14 +09:00
server_sampling_test.rb Support notifications/cancelled per MCP specification 2026-05-03 04:02:22 +09:00
server_session_ping_test.rb Support server-to-client ping per MCP specification 2026-05-22 11:28:51 +09:00
server_test.rb Conform Tool Schemas to JSON Schema 2020-12 per SEP-2106 2026-06-19 21:36:55 +09:00
string_utils_test.rb Fix ReDoS vulnerability in StringUtils#underscore 2026-01-09 01:14:52 +09:00
tool_test.rb Speed Up Tool::Schema Validation by 5x to 100x 2026-06-01 21:47:30 +09:00
trace_context_test.rb Support W3C Trace Context Propagation via _meta per SEP-414 2026-06-12 14:36:24 +09:00
transport_test.rb Remove redundant require statements 2025-08-02 00:57:31 +09:00