CVE-2026-54902
NoneCVSS
—
EPSS
0.4%
Published
Jul 1, 2026
CISA due date
—
Cloudanix analysis
Some Ruby applications can be crashed by specially crafted JSON unless a commonly used JSON library is updated.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- Library
- Class
- Use After Free
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
CVE-2026-54902 is a use-after-free in the Oj Ruby gem before version 3.17.2 when using SAJ parsing mode. During parsing, Oj::Parser can cache object keys of 35 bytes or longer without protecting the corresponding Ruby string objects from garbage collection. If Ruby callback code invoked during hash_end triggers garbage collection, the key string can be freed while native C code still retains a pointer to it. A later access to that stale pointer can crash the Ruby process with a segmentation fault. The published evidence indicates availability impact and memory corruption, with a crash observed at an attacker-influenced canary-style address such as 0x4242; reliable code execution has not been demonstrated.
Why it matters to the business
Applications or services that parse untrusted JSON using Oj SAJ mode may be vulnerable to remotely triggerable process crashes, causing intermittent outages, failed background jobs, API errors, or service instability. The current public risk signals are relatively low: EPSS is 0.253%, the issue is not in CISA KEV, is not reported as ransomware-used, and no public exploit maturity is indicated. However, because Oj is a common Ruby JSON component, organizations should still patch promptly anywhere untrusted JSON is parsed, especially internet-facing APIs and worker services that automatically restart after crashes.
How an attack unfolds
An attacker needs a code path where a Ruby application uses Oj::Parser in SAJ mode to parse attacker-controlled JSON and where parser callbacks can execute Ruby code during hash_end. The attacker supplies crafted JSON containing object keys at least 35 bytes long so that Oj caches the key internally. The callback behavior must trigger Ruby garbage collection while the native parser still holds a reference to the key. Once the key object is reclaimed, the parser later dereferences freed memory, leading to a segmentation fault and process termination. The practical outcome is denial of service against the parsing process; exploitation beyond crashing would require reliable heap manipulation and has not been publicly established from the available information.
How to fix it
Upgrade the Oj gem to version 3.17.2 or later wherever it is installed. If dependency constraints prevent immediate upgrade, avoid using SAJ mode for untrusted input, remove callback behavior that can trigger garbage collection during parsing, or switch affected parsing paths to a non-vulnerable JSON parser until patching is complete. Rebuild and redeploy Ruby application images, update Gemfile.lock, and ensure runtime containers or servers are not still loading older gem versions. As compensating controls, limit request body sizes, rate-limit unauthenticated JSON ingestion endpoints, isolate worker processes, and ensure process supervisors restart crashed services while patching is underway.
How to confirm the fix worked
Confirm dependency remediation by checking that Gemfile.lock, installed gems, application containers, and runtime hosts report oj version 3.17.2 or later. Run `bundle exec ruby -roj -e 'puts Oj::VERSION'` or equivalent in the deployed runtime context, not just the build environment. Review code for SAJ usage such as Oj::Parser, Oj::Saj, or handler callbacks implementing hash_end. Test representative JSON ingestion paths after upgrade, including payloads with long object keys, and verify that parsing completes without Ruby segmentation faults. Software composition analysis should flag oj versions earlier than 3.17.2 as vulnerable.
Typical attack path
- Identify a Ruby application endpoint, job queue, webhook, API, or file-processing path that accepts attacker-controlled JSON.
- Determine or infer that the application uses the Oj gem in SAJ mode, especially Oj::Parser callbacks.
- Send JSON containing object keys of 35 bytes or longer to exercise the vulnerable cached-key behavior.
- Trigger application callback logic that invokes or indirectly causes Ruby garbage collection during hash_end processing.
- Cause Oj native parser code to access a freed Ruby string VALUE.
- Crash the Ruby process, producing segmentation fault logs and service disruption.
How to detect it
To assess prior exploitation, review application logs, process supervisor logs, container logs, system journals, crash dumps, and APM error traces for Ruby segmentation faults around JSON parsing activity. Focus on services using the Oj gem in SAJ mode and correlate crashes with inbound HTTP requests, webhook deliveries, queue messages, uploaded JSON files, or API payloads containing object keys of 35 bytes or longer. Look for repeated worker restarts, container exits caused by SIGSEGV, core dumps from Ruby processes, and stack traces referencing Oj native extension functions or SAJ parser callbacks such as hash_end. Web and API logs may show bursts of malformed or unusual JSON immediately before crashes, but the most reliable artifacts are Ruby crash reports and core dumps. If core dumps are available, inspect backtraces for Oj parser frames and instruction pointers or fault addresses with attacker-controlled patterns such as 0x4242.
- oj (< 3.17.2)
- oj (3.17.1)
- oj (3.17.0)
- Oj::Parser
- Oj::Saj
- hash_end
- [BUG] Segmentation fault
- Segmentation fault (core dumped)
- SIGSEGV
- RIP: 0x0000000000004242
- pc 0x0000000000004242
- /gems/oj-3.17.1/
- /gems/oj-3.17.0/
- oj/saj
- CFUNC :parse
What your security team should do
- Inventory Ruby applications, containers, and background workers that include the Oj gem, prioritizing internet-facing JSON ingestion and webhook endpoints.
- Upgrade Oj to 3.17.2 or later and redeploy affected services from clean builds so older native extensions are not retained.
- Search application code for SAJ parser usage and callback methods such as hash_end, then prioritize those services for immediate validation.
- Add temporary request size limits and rate limiting on unauthenticated JSON endpoints until patching is complete.
- Monitor Ruby process crashes and segmentation faults for evidence of attempted exploitation, especially repeated crashes correlated with JSON requests containing long object keys.
- Create SCA or CI/CD policy gates to block oj versions earlier than 3.17.2 from new builds.
- Because the issue is not KEV-listed and has low EPSS, treat it as prompt patching rather than emergency response unless the affected service parses untrusted JSON in SAJ mode or crashes are observed.
The record
Oj (Optimized JSON) is a JSON parser and Object marshaller packaged as a Ruby gem. Prior to version 3.17.2, is vulnerable to Use-After-Free when in SAJ mode. The Oj::Parser does not protect cached object keys (≥ 35 bytes) from garbage collection, and a Ruby callback that triggers GC inside hash_end can cause the key string to be reclaimed while the C parser still holds a pointer to it. The subsequent access to the freed string VALUE results in a segfault, confirmed by an RIP pointing to address 0x4242 (a canary-style pattern suggesting control over the freed memory's content). This issue has been fixed in version 3.17.2.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-109618 PHP uses longjmp() for out-of-memory (OOM) errors to exit the current context and abort… CWE-416
- CVE-2026-109619 PHP has various global state that temporarily points into request memory. CWE-416
- CVE-2026-112402 Pillow is a Python imaging library. CWE-416
- CVE-2026-112396 Pillow is a Python imaging library. CWE-416
- CVE-2025-55654 A use-after-free in the gf_filter_pid_get_packet function (filter_core/filter_pid.c) of… CWE-416
- CVE-2026-17591 A flaw was found in libarchive. CWE-416
- CVE-2026-92392 During an upload, curl mishandles HTTP/2 `RST_STREAM` received from the server (with… CWE-416
- CVE-2026-109268 ImageMagick before 6.9.13-57 and 7.x before 7.1.2-32 contains a use after free… CWE-416