RustSec logo

History ⋅ Edit ⋅ JSON (OSV)

RUSTSEC-2026-0435

Unbounded memory allocation in thrift binary protocol read_bytes

Reported
Issued
Package
thrift (crates.io)
Type
Vulnerability
Categories
Keywords
#parsing #denial-of-service #allocation #thrift
Aliases
References
CVSS Score
7.5 HIGH
CVSS Details
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality Impact
None
Integrity Impact
None
Availability Impact
High
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Patched
  • >=0.23.0
Affected Functions
Version
thrift::protocol::binary::TBinaryInputProtocol::read_bytes
  • <0.23.0
thrift::protocol::binary::TBinaryInputProtocol::read_string
  • <0.23.0

Description

Affected versions of the thrift crate size a buffer directly from an attacker-controlled 4-byte length read off the wire, before reading any payload and with no upper bound, allowing a hostile peer to force a large eager allocation or an immediate abort (denial of service, CWE-400 / CWE-789). This is the Rust implementation's instance of the CVE-2020-13949 pattern, published by the Apache Thrift PMC as CVE-2026-43868.

Details

In TBinaryInputProtocol::read_bytes (src/protocol/binary.rs), the length is read as a i32 from the transport and cast straight to usize to size a zeroing buffer before any payload is read:

fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
    let num_bytes = self.transport.read_i32::<BigEndian>()? as usize; // length from the wire
    let mut buf = vec![0u8; num_bytes];                               // unbounded eager allocation
    self.transport.read_exact(&mut buf).map(|_| buf).map_err(From::from)
}

There is no check that num_bytes is non-negative or that it fits within the data actually available:

read_string routes through read_bytes, so string fields are affected the same way. The sink is reachable from any peer sending binary-protocol data, so this is an unauthenticated, network-reachable denial of service.

The fix

From thrift 0.23.0 onward, read_bytes goes through read_binary_len, which rejects negative sizes and enforces TConfiguration::max_string_size (default 100 MiB), alongside default message, frame, and recursion limits.

A separate, related gap on the non-strict message-name path was published as CVE-2026-58389 and fixed in 0.24.0; this advisory covers the read_bytes unbounded allocation (CVE-2026-43868), fixed in 0.23.0.

Advisory available under CC0-1.0 license.