Skip to main content

Oj gem CVE-2026-54896

LOW
Heap-based Buffer Overflow (CWE-122)
2026-06-19 https://github.com/ohler55/oj GHSA-35w3-pjm6-wj95
2.1
CVSS 4.0 · Vendor: https://github.com/ohler55/oj

Severity by source

Vendor (https://github.com/ohler55/oj) PRIMARY
2.1 LOW
CVSS:4.0/AV:L/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
3.0 LOW

Indent is a developer-controlled, non-public option so PR:H and AC:H; impact is realistically heap corruption causing crash, hence I:L/A:L and no confidentiality loss.

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

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

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

Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

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

DescriptionCVE.org

Summary

Oj.dump in object mode is vulnerable to a heap buffer overflow when serializing Exception objects with a large :indent value. The serializer allocates a buffer sized for the object's attributes but does not account for the indent bytes added on each write. With indent: 5000, the accumulation of 5,000-byte indent strings overflows the 13,150-byte heap allocation, corrupting adjacent heap memory.

Version

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

Details

ext/oj/dump.h, line 75-77:

c
static void fill_indent(Out out, int depth) {
    if (0 < out->opts->indent) {
        memset(out->buf + out->cur, ' ', (size_t)(out->opts->indent * depth));

When dumping an Exception object in :object mode, dump_obj_attrs calls fill_indent repeatedly for each attribute. The buffer is pre-allocated based on the serialized content but not the indentation overhead. With indent: 5000 the indent block for a nested object exceeds the remaining buffer space, producing a heap-buffer-overflow of size 5,000 at the end of the allocated region.

ASAN report:

==101656==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x527000022c5e
WRITE of size 5000 at 0x527000022c5e thread T0
    #0 memset
    #1 fill_indent       /ext/oj/dump.h:77
    #2 dump_obj_attrs    /ext/oj/dump_object.c:552
    #3 dump_obj          /ext/oj/dump_object.c:80
    #4 oj_dump_obj_val   /ext/oj/dump_object.c:708
    #5 oj_dump_obj_to_json_using_params  /ext/oj/dump.c:817
    #6 dump_body         /ext/oj/oj.c:1429
    #7 dump              /ext/oj/oj.c:1480
0x527000022c5e is located 0 bytes after 13150-byte region [0x52700001f900, 0x527000022c5e)

Reproduce

ruby
require "oj"
obj = Oj.load('{"^o":"RuntimeError"}', mode: :object)
Oj.dump(obj, mode: :object, indent: 5000)

Workarounds

This is at the discretion of the developer and not a public facing option so the workaround is the develop should not use extreme indents and should not offer the option for users to dump Ruby data with unlimited indentation size.

AnalysisAI

Heap buffer overflow in the Ruby Oj gem (versions before 3.17.3) occurs when Oj.dump serializes Exception objects in :object mode with an extreme :indent value. The pre-allocated output buffer does not account for indent padding bytes, allowing writes past the heap region and corrupting adjacent memory. No public exploit identified at time of analysis; the issue is triggered by developer-chosen serialization options rather than typical attacker-supplied input.

Technical ContextAI

Oj is a popular high-performance Ruby JSON parser/serializer with a C extension (ext/oj). The flaw lives in ext/oj/dump.h's fill_indent helper, which performs memset(out->buf + out->cur, ' ', indent * depth) without verifying the destination buffer has room. Buffer sizing in dump_obj_attrs (dump_object.c) accounts for serialized attribute content but omits cumulative indent padding, so deeply nested Exception serialization with large indent multiplies past the allocation - the ASAN trace shows a 5000-byte write at the boundary of a 13150-byte region. This is a classic CWE-122 heap-based buffer overflow rooted in incorrect size calculation.

RemediationAI

Upgrade the oj gem to the vendor-released patch version 3.17.3 (per the package metadata in the GitHub advisory at https://github.com/ohler55/oj/security/advisories/GHSA-35w3-pjm6-wj95) by updating the Gemfile constraint and running bundle update oj, then redeploying. As a temporary mitigation until the upgrade is rolled out, audit application code that calls Oj.dump and remove or cap the :indent option (e.g., reject indent values above a small bound such as 16) and never expose the indent parameter to untrusted input, with the trade-off that pretty-printed JSON output for legitimate use will be less configurable. Do not switch away from :object mode purely as a workaround unless you understand the deserialization implications, since :object mode itself has separate security considerations.

Share

CVE-2026-54896 vulnerability details – vuln.today

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