CVE-2026-54500
Medium · 5.3CVSS
5.3
EPSS
0.2%
Published
Jul 1, 2026
CISA due date
—
Cloudanix analysis
Some Ruby applications that parse JSON with a vulnerable library may accidentally reveal small pieces of private server memory when given specially crafted input.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Data Exposure
- Component
- Library
- Class
- Information Disclosure
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Oj versions prior to 3.17.3 contain an information disclosure flaw in `Oj.load` when used in `:object` mode. A JSON object key of 254 bytes or longer triggers incorrect handling in `ext/oj/intern.c`: the long-key path allocates and populates a heap buffer but passes an uninitialized stack buffer to `rb_intern3()`. For keys of 256 bytes or longer, the code can also read past the end of the 256-byte stack buffer. The resulting bytes may be interned as a Ruby Symbol or exposed in an `EncodingError` message, allowing disclosure of process stack memory. The issue affects confidentiality only; it does not directly provide code execution, privilege escalation, or data modification.
Why it matters to the business
Applications that parse untrusted JSON with vulnerable versions of the Oj Ruby gem may leak fragments of in-process memory to remote unauthenticated users. Depending on what is present on the stack at parse time, leaked data could include request data, tokens, secrets, internal identifiers, or other sensitive application context. The CVSS score is moderate and EPSS is currently very low, with no known KEV listing or public exploit maturity reported, but internet-facing APIs that accept JSON and use `Oj.load` in object mode should still be prioritized because exploitation can be simple and unauthenticated.
How an attack unfolds
An attacker sends crafted JSON to an application endpoint that parses attacker-controlled input using a vulnerable Oj version and `Oj.load` in `:object` mode. The payload contains an object key at least 254 bytes long. During parsing, Oj takes the long-key handling path and incorrectly interns bytes from an uninitialized stack buffer instead of the populated heap buffer. If the bytes are accepted, the application may receive a Symbol containing leaked stack bytes; if the bytes are invalid UTF-8, the error path may include leaked bytes in an `EncodingError` message. The attacker then observes the application response, error output, logs exposed through diagnostics, or other returned parsing results to recover fragments of process memory. Repeated requests may expose different stack contents over time.
How to fix it
Upgrade the Oj Ruby gem to version 3.17.3 or later everywhere it is used. Rebuild and redeploy application containers, packages, and lockfiles so the runtime actually loads the fixed gem version. If immediate upgrade is not possible, avoid using `Oj.load` in `:object` mode on untrusted input, switch to safer parsing modes such as strict JSON parsing where compatible, and reject or cap unusually long JSON object keys before parsing. Disable detailed exception responses to clients and avoid logging raw parser exception messages containing attacker-supplied JSON or binary data. Because the issue can expose in-process secrets, consider rotating credentials that may have been resident in memory for high-risk exposed services after patching.
How to confirm the fix worked
Confirm that dependency manifests and runtime package inventories show Oj version 3.17.3 or later. In Ruby environments, validate with commands such as `bundle info oj`, `bundle exec ruby -roj -e 'puts Oj::VERSION'`, or equivalent application-runtime checks. Review lockfiles such as `Gemfile.lock` to ensure no vulnerable version remains in deployed artifacts. Test exposed JSON parsing paths with oversized object keys and verify they do not return unexpected bytes or verbose `EncodingError` details. Confirm web and application error handling returns generic errors and that logs do not include leaked binary stack fragments from parser failures.
Typical attack path
- Identify a Ruby application or API endpoint that accepts JSON input.
- Determine or infer that the application uses the Oj gem and parses input with `Oj.load` in `:object` mode.
- Send a JSON object containing a key of 254 bytes or longer; use 256 bytes or longer to also trigger the out-of-bounds read behavior.
- Observe whether the parsed result, serialized response, validation error, exception message, or debug output contains unexpected bytes.
- Repeat requests to collect stack memory fragments and search the output for secrets, tokens, session material, request data, or internal values.
How to detect it
Look for evidence of JSON requests containing object keys of 254 bytes or longer sent to endpoints handled by Ruby services using Oj. Useful sources include web access logs, reverse proxy logs, WAF events, API gateway logs, application logs, error tracking systems, and Ruby exception telemetry. Search for repeated malformed JSON submissions, unusually long JSON field names, HTTP 4xx or 5xx responses associated with JSON parsing, and `EncodingError` or Oj parser errors after requests with large object keys. Also review response bodies captured by test, proxy, or error systems for unexpected binary data, invalid UTF-8 fragments, escaped byte sequences, or symbol-like values derived from long JSON keys. There are no known public threat actors or KEV activity associated with this issue, so detection should focus on behavioral artifacts rather than actor-specific infrastructure.
- Oj::VERSION < 3.17.3
- Oj.load
- mode: :object
- :object
- EncodingError
- invalid byte sequence in UTF-8
- JSON object key length >= 254
- JSON object key length >= 256
- HTTP request body containing a JSON key of 254 or more bytes
- HTTP request body containing a JSON key of 256 or more bytes
What your security team should do
- Inventory Ruby applications, services, background workers, and containers that include the Oj gem.
- Prioritize internet-facing or partner-facing services that parse untrusted JSON with `Oj.load` in `:object` mode.
- Upgrade Oj to 3.17.3 or later and redeploy all affected workloads from clean builds.
- Search code for `Oj.load` usage and require explicit safe parsing modes for untrusted data.
- Add input validation or request filtering for unusually long JSON object keys where business logic does not require them.
- Review application logs, error tracking systems, and API responses for evidence of oversized-key parsing attempts or leaked binary data.
- Ensure production error responses do not expose raw exception messages, stack traces, or parser diagnostics to users.
- For high-sensitivity services, rotate secrets that may have been exposed in process memory if suspicious exploitation attempts are found.
The record
Oj (Optimized JSON) is a JSON parser and Object marshaller packaged as a Ruby gem. In versions prior to 3.17.3, Oj.load in :object mode reads uninitialized stack memory (and, for long keys, reads out of bounds) when parsing a JSON object whose key is 254 bytes or longer. The interned bytes can surface to the caller, disclosing process stack memory. In ext/oj/intern.c, form_attr() handles the long-key path by allocating a heap buffer, `b`, populating it with the attribute name, and then freeing it — but it passed the uninitialized stack buffer buf (not b) to rb_intern3(). rb_intern3 therefore reads len + 1 bytes of uninitialized stack memory. When the key length is >= 256, it also reads out of bounds past the 256-byte buf. The resulting bytes are interned and can reach the caller via the produced Symbol or via the EncodingError message raised on invalid UTF-8, leaking process stack contents. This issue has been fixed in version 3.17.3.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-92824 A flaw was found in libmodulemd. CWE-125
- CVE-2026-114038 A flaw was found in device-mapper-multipath. CWE-125
- CVE-2026-112896 Pillow is a Python imaging library. CWE-125
- CVE-2026-112278 rdesktop through 1.9.0 contains a heap out-of-bounds read vulnerability in… CWE-125
- CVE-2026-112273 libtins through 4.6 contains a heap out-of-bounds read vulnerability in DNS::compose_name… CWE-125
- CVE-2026-112073 A vulnerability was identified in Tencent ncnn up to 44b02dabdcf97499281a4692ebd65bad73dc… CWE-125
- CVE-2026-112020 LodePNG through 20261006 contains a heap out-of-bounds read vulnerability in… CWE-125
- CVE-2026-88842 A flaw was found in BusyBox dpkg. CWE-125