Dmytro Shteflyuk created THRIFT-6126:
----------------------------------------
Summary: Ruby SimpleServer stops accepting clients after unknown
Compact or JSON types
Key: THRIFT-6126
URL: https://issues.apache.org/jira/browse/THRIFT-6126
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
The Ruby Compact and JSON protocol implementations do not consistently classify
unknown wire type identifiers as protocol errors.
Compact Protocol raises a generic runtime error for an unknown field or
container type. JSON Protocol raises {{NotImplementedError}} for an unknown
type name or identifier. These exceptions fall outside the per-connection
protocol error handling used by {{SimpleServer}}. As a result, a malformed
request can escape the connection-processing path and stop the server's accept
loop instead of only closing that client connection.
The native and pure-Ruby Compact implementations also differ when reporting an
invalid type supplied by a writer: the pure implementation masks the value
before constructing its error message. The Ruby fuzz harness consequently
relies on matching several error-message strings that now represent typed
protocol errors.
h3. Client impact
A Ruby {{SimpleServer}} may stop accepting new clients after receiving a
request containing an unknown Compact or JSON field or container type. Existing
applications then need to restart the server before later clients can connect
successfully.
The inconsistent exception classes and Compact error values also make
malformed-input handling depend on the selected protocol implementation and
whether the native extension is loaded.
h3. Reproduction
Compact Protocol:
{code:ruby}
require "thrift"
transport = Thrift::MemoryBufferTransport.new([0x1e].pack("C"))
protocol = Thrift::CompactProtocol.new(transport)
protocol.read_field_begin
{code}
The invalid Compact type {{14}} currently raises a generic error such as:
{noformat}
StandardError: don't know what type: 14
{noformat}
JSON Protocol:
{code:ruby}
require "thrift"
payload = '[1,"unknown",1,1,{"1":{"wat":0}}]'
transport = Thrift::MemoryBufferTransport.new(payload)
protocol = Thrift::JsonProtocol.new(transport)
protocol.read_message_begin
protocol.read_struct_begin
protocol.read_field_begin
{code}
The unknown JSON type {{wat}} currently raises {{NotImplementedError}}.
When either payload reaches {{SimpleServer}}, the exception can escape its
per-connection handling and terminate the accept loop. A later valid client is
therefore not processed.
h3. Expected behavior
Unknown Compact and JSON field or container types should raise
{{Thrift::ProtocolException}} with type {{INVALID_DATA}} and a useful message.
{{SimpleServer}} should treat that exception as belonging to the malformed
connection, close that connection, and continue accepting later clients. Native
and pure-Ruby Compact implementations should expose the same exception metadata
and preserve the original invalid writer type in the message.
The fuzz harness should rely on the typed protocol exception rather than
matching obsolete error-message strings.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)