Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
💎 RubyGems
Not in CISA KEV

CVE-2026-54896 — oj

CVE-2026-54896 is a CWE-122 vulnerability in oj. A fix is available for oj — see the affected versions and patch details below.

Oj: Heap Buffer Overflow in Oj.dump Exception Serialization via Large Indent

Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 20, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-54896.

EPSS Exploitation Probability

via FIRST.org ↗
0.1%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs4th percentile — riskier than 4% of all scored CVEsHighest risk
0.00%0.22%0.44%0.67%0.1%0.1%0.2%0.1%0.1%Jul 26Sep 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected
💎oj

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects RubyGems packages — download data is not available via public APIs for these ecosystems.

Description

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:

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

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.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
💎RubyGemsojall versions3.17.3bundle update oj --conservative

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for oj, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update oj to 3.17.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-54896 is resolved across your whole dependency graph.

  3. Workarounds

    Stop feeding it untrusted input: reject or quarantine files and payloads from unverified sources until you can upgrade, restrict accepted formats to the ones you actually need, and run the parsing or decoding step in a least-privileged sandbox or short-lived worker so a crash or corrupted read cannot reach the rest of the process.

Frequently Asked Questions

### 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
O3 Security · Impact-Aware SCA

Is CVE-2026-54896 in your dependencies?

Find it across RubyGems, including transitive dependencies.

CVE-2026-54896: oj Memory Corruption — Fixed in 3.17.3