msgpack-ruby JRuby decoder makes uncapped header-count allocations; a 5-byte message forces multi-GiB OOM
Published: October 30, 2026
SECURITY IDENTIFIERS
- CVE: CVE-2026-126366 (NVD)
- GHSA: GHSA-73v3-wf97-vpgj
GEM
PLATFORM
SEVERITY
CVSS v3.x: 7.5 (High)
PATCHED VERSIONS
>= 1.8.7
DESCRIPTION
Summary
The JRuby implementation of msgpack (msgpack gem,
java platform — pure Java decoder under ext/java/) sizes containers
directly from the element count written in the message header, with
no cap at all: no equivalent of the C unpacker's SHRT_MAX clamp
(since 1.7.3) and none of the buffered-bytes cap that commit c8d42d8
added for CRuby in 1.8.6. A single 5-byte message decides how much
memory a JVM process tries to allocate:
-
array32header declaring0x7FFFFFFFelements →new IRubyObject[0x7FFFFFFF](~8 GiB of reference slots) attempted immediately →java.lang.OutOfMemoryError: Requested array size exceeds VM limit. -
Counts below the VM's max-array-size but above available heap (e.g. 5×10⁸ with a 512 MiB heap) produce a real allocation attempt —
OutOfMemoryError: Java heap space— the JVM genuinely tries to take the memory before failing. -
str32/bin32headers declaring0x7FFFFFFFbytes do the same viareadBytes(size)→new byte[size]. -
Below the failure threshold there is a silent band: one streaming unpacker fed only an
array32header with count 2×10⁷ (5 wire bytes, zero elements) grows used heap +78 MiB immediately, no exception (eachswallows the underflow), and the footprint stays elevated afterUnpacker#reset+ full GC. Linear in declared count (~4 B/element); nothing bounds it — not delivered bytes, not a per-container cap.
Only counts ≥ 2³¹ are refused (a clean MessagePack::UnderflowError
from getUnsignedInt()), and only maps are safe (consumeHash
grows per element instead of pre-sizing). Verified on the released
gem msgpack 1.8.6 java, JRuby 9.4.12 / OpenJDK 25, 2026-10-30 —
i.e. unfixed in the current release. Proposed fix mirrors
c8d42d8: cap initial allocation by bytes actually buffered and
grow as data arrives; read strings in bounded chunks instead of
allocating the declared length up front.
Impact
Type. Uncontrolled resource consumption driven by declared sizes rather than delivered bytes — CWE-770 (Allocation of Resources Without Limits or Throttling), precisely CWE-1325 (Independent Resource Usage Limiting Not Applied). Availability only; no confidentiality/integrity impact, no code execution.
Who is impacted. Any JRuby application that feeds untrusted msgpack
to MessagePack.unpack/Unpacker — the java-platform gem's whole
user base (JRuby-based services, log/RPC pipelines, JVM polyglot
stacks using this gem). For them: remote OOM of a shared-heap JVM
from a 5-byte message, or silent heap spend below the exception band.
RELATED
- https://nvd.nist.gov/vuln/detail/CVE-2026-126366
- https://rubygems.org/gems/msgpack/versions/1.8.7
- https://github.com/msgpack/msgpack-ruby/releases/tag/v1.8.7
- https://github.com/msgpack/msgpack-ruby/commit/ca0efc1256c687b428c46dd68ce000ff515d53f2
- https://advisories.gitlab.com/gem/msgpack/CVE-2026-126366
- https://github.com/msgpack/msgpack-ruby/security/advisories/GHSA-73v3-wf97-vpgj
- https://github.com/advisories/GHSA-73v3-wf97-vpgj
