Oj gem CVE-2026-54903
MEDIUMSeverity by source
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
Network-reachable via any endpoint calling Oj.load; AC:H because exploitation requires delivering a >2GB payload past typical body limits; PR:N/UI:N; impact is process crash, so only A:H.
Primary rating from Vendor (https://github.com/ohler55/oj).
CVSS VectorVendor: https://github.com/ohler55/oj
Lifecycle Timeline
3DescriptionCVE.org
Summary
Oj.load is vulnerable to heap corruption when parsing a JSON string longer than 2 GB. An integer overflow in buf_append_string (buf.h:61) converts the string length to a large negative size_t, causing memcpy to copy an astronomically large amount of data out of bounds. This crashes the process and can corrupt adjacent heap memory.
Version
- Software: oj gem
- Affected: all versions with
ext/oj/buf.handext/oj/parse.c - Latest tested: 3.17.1 (confirmed present)
Details
ext/oj/buf.h, line 61:
inline static void buf_append_string(Buf buf, const char *s, size_t slen) {
// ...
memcpy(buf->tail, s, slen); // slen derived from 32-bit int that wrapped negativeIn parse.c, escape sequence handling computes the remaining string length as an int:
// parse.c:402 (read_escaped_str)
int slen = (int)(s - str); // ← wraps to negative when string > 2 GB
buf_append_string(buf, str, (size_t)slen); // ← (size_t)(-2147483648) = 0x80000000...ASAN report:
==399019==ERROR: AddressSanitizer: negative-size-param: (size=-2147483648)
#0 __asan_memcpy
#1 buf_append_string /ext/oj/buf.h:61
#2 read_escaped_str /ext/oj/parse.c:402
#3 read_str /ext/oj/parse.c:542
#4 oj_parse2 /ext/oj/parse.c:882
#5 oj_pi_parse /ext/oj/parse.c:1256
#6 oj_object_parse /ext/oj/object.c:701
#7 load /ext/oj/oj.c:1259
0x7f5a26ff0801 is located 1 bytes inside of 2147483657-byte region [0x7f5a26ff0800, 0x7f5aa6ff0809)Reproduce
require 'oj'
n = 1 << 31
# 2 GB
json = '"' + ('A' * n) + 'A"'
# >2GB JSON string with a trailing escape
Oj.load(json)AnalysisAI
Heap corruption in the Ruby Oj JSON parser (Oj.load) is triggered when applications process attacker-controlled JSON strings larger than 2 GB containing an escape sequence, due to an integer overflow in read_escaped_str that wraps a 32-bit length to a negative value and is then cast to size_t, causing memcpy to copy ~2 GB out of bounds. Versions of the oj gem prior to 3.17.3 are affected, and no public exploit identified at time of analysis; CVSS and EPSS are not provided.
Technical ContextAI
Oj is a widely used C-extension JSON parser for Ruby (CPE pkg:rubygems/oj), commonly used as a faster drop-in for Ruby's stdlib JSON. The root cause is CWE-190 (Integer Overflow or Wraparound): in ext/oj/parse.c:402 (read_escaped_str), the remaining string length is computed as int slen = (int)(s - str), which wraps to a negative value when the input exceeds 2^31 bytes. That value is cast to size_t and passed to buf_append_string in ext/oj/buf.h:61, where memcpy(buf->tail, s, slen) then reads ~2 GB out of bounds, corrupting adjacent heap memory and typically crashing the Ruby process, as evidenced by the AddressSanitizer negative-size-param report in the GHSA advisory.
RemediationAI
Vendor-released patch: upgrade the oj gem to version 3.17.3 or later (advisory GHSA-475m-ph3x-64gp at https://github.com/ohler55/oj/security/advisories/GHSA-475m-ph3x-64gp), e.g. by pinning gem 'oj', '>= 3.17.3' in the Gemfile and running bundle update oj. As a compensating control until patched, enforce a hard input-size limit well below 2 GB on any code path that feeds untrusted data into Oj.load - for HTTP services this typically means setting Rack/Nginx client_max_body_size (e.g. 10-100 MB) and validating JSON payload length before parsing, which has minimal side effects for normal traffic but will reject legitimate very large uploads; alternatively, route untrusted JSON through Ruby's stdlib JSON.parse until the upgrade is deployed, accepting a performance penalty.
Same weakness CWE-190 – Integer Overflow or Wraparound
View allSame technique Denial Of Service
View allVendor StatusVendor
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-475m-ph3x-64gp