Dmytro Shteflyuk created THRIFT-6131:
----------------------------------------

             Summary: Bound Ruby HeaderTransport varint32 parsing
                 Key: THRIFT-6131
                 URL: https://issues.apache.org/jira/browse/THRIFT-6131
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
            Reporter: Dmytro Shteflyuk
            Assignee: Dmytro Shteflyuk


h3. Problem

Ruby HeaderTransport accepts a variable-length uint32 until the Header boundary 
rather than enforcing the five-byte width of a uint32. A malformed Header with 
continuation bytes can therefore be read across the full Header area before 
rejection.

h3. Client impact

A malformed Header frame can spend unnecessary time in Ruby parsing before it 
is rejected. HeaderTransport should reject an overlong or out-of-range uint32 
at the fifth byte while retaining valid five-byte values.

h3. Reproduction

On an unpatched checkout, from the repository root, run:

{code:sh}
cd lib/rb
bundle exec ruby -Ilib -e '
require "thrift"

header_data = "\x80".b * 65_532
frame = [10 + header_data.bytesize].pack("N")
frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack("n")
frame << [0].pack("n")
frame << [0].pack("N")
frame << [header_data.bytesize / 4].pack("n")
frame << header_data

transport = 
Thrift::HeaderTransport.new(Thrift::MemoryBufferTransport.new(frame))
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
begin
  transport.read(1)
rescue Thrift::TransportException => error
  elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
  puts "#{error.message}; elapsed=#{format("%.4f", elapsed)}s"
end
'
{code}

The pre-change reader was executed from base {{4e9e407e}} against this frame in 
the dedicated pure-Ruby container. It consumed all 65,532 continuation bytes 
and printed:

{code}
Trying to read past header boundary; elapsed=0.0085s
{code}

h3. Expected behavior

HeaderTransport accepts at most five varint32 bytes. The fifth byte must 
terminate and contain only {{0x00..0x0f}}. A fifth-byte continuation is 
rejected as overlong, and a terminating fifth byte above {{0x0f}} is rejected 
as a uint32 overflow.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to