Ruby JSON - JSON::ResumableParser#partial_value dereferences a freed input buffer and crashes on truncated duplicate-key streams
Published: August 07, 2026
SECURITY IDENTIFIERS
- CVE: CVE-2026-71847 (NVD)
- GHSA: GHSA-9hj4-r449-hfvc
GEM
UNAFFECTED VERSIONS
< 2.20.0
PATCHED VERSIONS
>= 2.21.2
DESCRIPTION
Summary
Ruby's JSON native C extension clears the consumed JSON::ResumableParser
input buffer but leaves state.start, state.cursor, and state.end
pointing into released storage.
When partial_value reconstructs an incomplete object containing
duplicate keys, the duplicate-key warning path calls cursor_position,
which dereferences those stale pointers. This results in a
heap-use-after-free and can terminate the Ruby process.
An attacker who can supply JSON stream data to an application using
JSON::ResumableParser may cause process termination when the
application calls partial_value on incomplete attacker-controlled
input containing duplicate object keys.
The issue was reproduced in the native C extension from the official RubyGems releases:
- JSON 2.20.0
- JSON 2.21.0
- JSON 2.21.1
The attached evidence demonstrates:
- an AddressSanitizer-confirmed heap-use-after-free;
- a native
SIGSEGVusing the official JSON 2.21.1 RubyGem; - an end-to-end loopback TCP attacker/victim reproduction;
- four differential controls;
- successful execution after applying a tested patch control.
This was originally reported privately through Ruby's HackerOne program
as report #3867755. A Ruby maintainer independently confirmed
reproduction of the ASan failure and requested that further
coordination continue through this private advisory.
No code execution or information disclosure is claimed.
Impact
This is a use-after-free that can result in native Ruby process termination.
An attacker must be able to supply JSON stream data to an application that:
- uses
JSON::ResumableParser; - processes attacker-controlled streaming input;
- calls
partial_valueafter parsing an incomplete document containing duplicate object keys.
In network-facing deployments meeting these conditions, an attacker can cause process termination and denial of service.
The release-build crash was reproduced consistently in the tested Linux environment. The AddressSanitizer result confirms the underlying heap-use-after-free independently of normal allocator behavior.
The demonstrated impact is:
Denial of service through native process termination
No confidentiality impact, integrity impact, arbitrary code execution, or information disclosure is claimed.
RELATED
- https://nvd.nist.gov/vuln/detail/CVE-2026-71847
- https://rubygems.org/gems/json/versions/2.21.2
- https://github.com/ruby/json/blob/master/CHANGES.md#2026-07-31-2212
- https://github.com/ruby/json/releases/tag/v2.21.2
- https://advisories.gitlab.com/gem/json/CVE-2026-71847
- https://osv.dev/vulnerability/GHSA-9hj4-r449-hfvc
- https://github.com/ruby/json/security/advisories/GHSA-9hj4-r449-hfvc
- https://github.com/advisories/GHSA-9hj4-r449-hfvc
