Cloudanix VulnDB

CVE-2026-54898

None

CVSS

—

EPSS

0.1%

Published

Jul 1, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A Ruby JSON parsing library can crash certain applications if parsing callbacks modify the data being parsed, so affected software should be updated.

Exploitation
Local Privilege
Attacker needs
Local User
Complexity
Moderate
Impact
Denial Of Service
Component
Library
Class
Use After Free
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Oj versions prior to 3.17.2 contain a heap use-after-free in Oj::Parser#parse when using SAJ/SAJ2-style callbacks. During parsing, the native C engine keeps a raw pointer into a Ruby String buffer; if a callback mutates or resizes that same input string, such as replacing it with a longer value, Ruby can reallocate the buffer and free the memory the parser still references. The next parser read can then dereference stale memory, resulting in process instability, memory-safety faults, or a crash. Based on the published scoring, the practical impact is primarily local availability loss rather than confirmed remote code execution or data compromise.

Why it matters to the business

Applications or background jobs that use vulnerable Oj parsing with callbacks may crash when processing crafted or unusual JSON flows that trigger input mutation during parsing. The most likely operational consequence is intermittent service failure, job interruption, or degraded availability in Ruby services that depend on Oj. The issue is not in CISA KEV, has very low EPSS, and has no reported exploit maturity, so urgency is lower than actively exploited internet-facing vulnerabilities, but affected systems should still be upgraded because memory-safety bugs can be difficult to reason about and may become more serious as research matures.

How an attack unfolds

An attacker first needs a way to influence a Ruby execution path that invokes Oj::Parser#parse with SAJ or SAJ2 callbacks and causes one of those callbacks to mutate the same JSON input string while parsing is still in progress. The attacker then supplies JSON that reaches the vulnerable callback sequence. When the callback resizes the original Ruby String, Ruby may move the string data to a new heap allocation and free the old buffer. The native Oj parser continues using its stale pointer into the freed buffer; on the next character read, the process can hit a use-after-free condition and crash. In most deployments, exploitation is likely constrained to denial of service because it depends on application-specific callback behavior and there is no public indication of reliable code execution.

How to fix it

Upgrade the Oj Ruby gem to version 3.17.2 or later wherever it is installed. If immediate upgrade is not possible, review all uses of Oj::Parser#parse with SAJ/SAJ2 callbacks and ensure callbacks do not mutate the input JSON String being parsed. As a defense-in-depth mitigation, pass an immutable or duplicated copy into the parser, avoid String#replace or other resizing operations on the parsed buffer during callbacks, and isolate JSON parsing in worker processes that can fail safely without taking down critical services. Rebuild and redeploy all application images, bundles, and lockfiles that pin Oj below 3.17.2.

How to confirm the fix worked

Confirm dependency resolution shows Oj 3.17.2 or later, for example through Gemfile.lock, bundle list, gem list oj, container SBOMs, and production artifact manifests. Search source code for Oj::Parser#parse, SAJ, SAJ2, hash_start, array_start, and callbacks that call String#replace, String#concat, String#<<, force_encoding, clear, or other mutating String methods on the input buffer. Run regression tests that exercise SAJ/SAJ2 parsing paths after the upgrade. For high-assurance validation, run targeted tests under AddressSanitizer or Ruby crash monitoring and verify the prior use-after-free or segmentation fault signature is no longer reproducible.

Typical attack path

  1. Identify a Ruby application, worker, plugin, or local script that uses Oj versions before 3.17.2.
  2. Find a code path that uses Oj::Parser#parse with SAJ or SAJ2 callbacks.
  3. Determine whether a callback can mutate or resize the same input JSON String during parsing.
  4. Provide JSON input that drives execution into the mutating callback path.
  5. Trigger String reallocation while the native parser still holds a pointer to the previous buffer.
  6. Cause the parser to dereference freed memory, leading to a crash or other memory-safety failure.

How to detect it

There are no public, reliable network indicators for prior exploitation because exploitation depends on in-process Ruby callback behavior rather than a distinctive remote payload. To assess whether the issue was triggered, review application logs, process supervisor logs, container logs, Ruby crash reports, core dumps, APM error traces, and system logs for crashes involving Oj::Parser#parse, SAJ/SAJ2 callbacks, or native faults in the Oj extension. Look for segmentation faults, bus errors, allocator errors, AddressSanitizer use-after-free reports, or repeated worker restarts occurring while processing JSON. Correlate crash timestamps with inbound requests, queue messages, file imports, or API payloads containing JSON, especially where the same endpoint or job repeatedly causes parser crashes. If core dumps are available, inspect native backtraces for Oj parser frames and Ruby String mutation callbacks such as hash_start or array_start. Absence of these artifacts does not prove absence of exposure; it only suggests the vulnerable condition has not obviously crashed the process.

  • Oj::Parser#parse
  • parser.c:607
  • heap-use-after-free
  • use-after-free
  • AddressSanitizer: heap-use-after-free
  • SEGV
  • SIGSEGV
  • segmentation fault
  • bus error
  • Oj::Saj
  • Oj::Saj2
  • hash_start
  • array_start
  • String#replace
  • oj-3.17.1
  • oj-3.17.0
  • oj (3.17.1)
  • oj (3.17.0)

What your security team should do

  • Inventory Ruby applications, containers, gems, and build artifacts for Oj versions earlier than 3.17.2.
  • Prioritize upgrading internet-facing services, shared parsing libraries, queue workers, and systems that process untrusted JSON, even though current exploitation likelihood is low.
  • Patch by updating Oj to 3.17.2 or later and redeploying all affected application artifacts rather than relying only on source dependency changes.
  • Review SAJ/SAJ2 callback implementations for mutation of the parsed input string and refactor unsafe callback behavior.
  • Add dependency scanning or SBOM policy gates to prevent introduction of Oj versions below 3.17.2.
  • Monitor application crash logs for segmentation faults, aborts, or sanitizer findings involving Oj::Parser#parse or parser.c around the vulnerable read path.
  • Because this is not KEV-listed and has very low EPSS, treat remediation as standard-priority unless the affected parser is reachable through untrusted JSON processing or causes high-availability services to crash.

The record

Oj (Optimized JSON) is a JSON parser and Object marshaller packaged as a Ruby gem. In versions prior to 3.17.2,Oj::Parser#parse is vulnerable to a heap use-after-free when a SAJ/SAJ2 callback mutates the input JSON string during parsing. The C engine holds a raw const byte * pointer into the Ruby string's internal buffer. If a callback (e.g. hash_start) resizes the string — for example by calling String#replace with a longer value — Ruby reallocates the string buffer and frees the old one. The C parser's pointer is left dangling; the next character read at parser.c:607 is a use-after-free. This issue has been fixed in version 3.17.2.

Affected packages

Ecosystem Package Introduced Fixed

Related vulnerabilities