Skip to main content

Oj gem CVE-2026-54902

MEDIUM
Use After Free (CWE-416)
2026-06-19 https://github.com/ohler55/oj GHSA-m578-w5vf-rfcm
6.3
CVSS 4.0 · Vendor: https://github.com/ohler55/oj
Share

Severity by source

Vendor (https://github.com/ohler55/oj) PRIMARY
6.3 MEDIUM
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/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:X
vuln.today AI
5.9 MEDIUM

Remote attacker-controlled JSON reaches a SAJ handler over the network without auth (AV:N/PR:N/UI:N); exploitation needs a long key plus GC inside the callback, so AC:H; demonstrated impact is process crash (A:H), no confirmed C/I.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/ohler55/oj).

CVSS VectorVendor: https://github.com/ohler55/oj

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/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:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

3
CVSS changed
Jul 01, 2026 - 00:22 NVD
6.3 (MEDIUM)
Source Code Evidence Fetched
Jun 19, 2026 - 21:35 vuln.today
Analysis Generated
Jun 19, 2026 - 21:35 vuln.today

DescriptionCVE.org

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

ruby
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

AnalysisAI

Use-after-free in the Oj Ruby JSON gem's SAJ parser allows an attacker who can influence parsed JSON content and the SAJ callback handler to crash the Ruby process and potentially corrupt memory. Oj::Parser fails to protect heap-allocated cached object keys of 35 bytes or more from garbage collection, so a GC cycle triggered from inside a hash_end callback frees the key while C code still holds a dangling VALUE pointer. …

Unlock full vulnerability intelligence

  • Risk assessment & exploitation conditions
  • Attack chain visualization
  • Remediation with exact patch versions
  • Threat intelligence from 22 sources
  • Personal watchlist & email alerts

Free forever · No credit card required

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata

Access
Identify endpoint parsing JSON with Oj SAJ
Delivery
Submit JSON with 35+ byte key
Exploit
Trigger GC inside hash_end callback
Execution
Free cached key VALUE
Persist
Parser dereferences dangling pointer
Impact
Ruby worker segfaults (DoS)

Vulnerability AssessmentAI

Exploitation The target application must (1) use Oj::Parser.new(:saj) - not Oj.load DOM mode and not the legacy Oj::Saj API - with a custom handler, (2) parse attacker-controlled JSON, (3) include an object key of 35 bytes or more so the key is heap-allocated rather than stack-inlined, and (4) execute a SAJ callback (notably hash_end, or add_value as in the PoC) that triggers a Ruby garbage collection cycle, either explicitly via GC.start or implicitly via allocations during the callback. … Additional conditions and limiting factors are described in the full assessment.
Risk Assessment No CVSS vector is supplied by NVD or the vendor, so all severity inference is qualitative. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in.
Exploit Scenario An attacker submits a JSON document with an outer object whose key is at least 35 bytes (e.g. 35 'A' characters) and a nested value that causes the application's SAJ callback to allocate enough to trigger a GC cycle inside hash_end; the parser then dereferences the freed key VALUE, segfaulting the Ruby worker. …
Remediation Vendor-released patch: upgrade the oj gem to 3.17.3 or later (bundle update oj and pin '~> 3.17.3' in the Gemfile), which is the fixed version recorded in the GHSA advisory at https://github.com/ohler55/oj/security/advisories/GHSA-m578-w5vf-rfcm. … Detailed patch versions, workarounds, and compensating controls in full report.

Recommended ActionAI

24 hours: Identify all applications and dependencies using Oj gem; retrieve GHSA advisory and published reproducer for technical assessment; enable application monitoring for unexpected process exits. …

Sign in for detailed remediation steps and compensating controls.

Threat intelligence, references, and detailed analysis are available after sign-in.

Share

CVE-2026-54902 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy