[
https://issues.apache.org/jira/browse/THRIFT-6131?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Dmytro Shteflyuk resolved THRIFT-6131.
--------------------------------------
Fix Version/s: 0.25.0
Resolution: Fixed
> 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
> Priority: Major
> Fix For: 0.25.0
>
> Time Spent: 0.5h
> Remaining Estimate: 0h
>
> 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)