A critical integer overflow in the yajl-ruby gem can corrupt memory and crash Ruby applications that parse exceptionally large JSON payloads on 32-bit builds. The flaw—tracked as CVE-2022-24795—affects all releases up to and including version 1.4.2 and has been patched in version 1.4.3. If your Ruby stack accepts JSON input from untrusted sources, upgrade immediately or enforce strict size limits to prevent denial-of-service attacks.
What actually changed
The vulnerability lives in ext/yajl/yajl_buf.c, the C extension that handles buffer reallocation during JSON parsing. When the parser needs to grow an internal buffer to accommodate roughly 0x80000000 bytes (about 2 GB), a 32-bit length calculation wraps to zero. The code then calls realloc with this tiny size, obtains a small memory chunk, and proceeds to write data using the original much-larger expected size. The result is a heap buffer overflow, corruption of heap metadata, and a hard process crash.
The bug is platform-dependent. On true 64-bit builds where size_t is 64 bits, the arithmetic wrap is practically unreachable. On 32-bit Ruby builds—common in minimal containers, embedded systems, or when compiling with -m32—an attacker can trigger the overflow by sending a specially crafted JSON payload that forces the buffer to grow near the 2 GB boundary. The advisory notes that version 1.4.2 tried to fix the heap corruption but introduced a possible infinite loop; therefore the definitive safe target is yajl-ruby 1.4.3 or later.
What it means for you
If you're a solo developer or hobbyist
Your personal Rails app or data-processing script is unlikely to be a target unless it accepts arbitrary JSON from the open internet. Still, upgrading takes a moment: bump the gem constraint in your Gemfile to gem 'yajl-ruby', '>= 1.4.3' and run bundle update. This closes the hole before it ever matters.
If you manage production Ruby services
For any internet-facing API endpoint, webhook receiver, or file-upload handler that uses yajl-ruby under the hood, this is a high-priority fix. An unauthenticated attacker can send a single multi-gigabyte JSON POST request—or a chunked transfer that builds such a payload—to crash a worker process. Repeating the attack can exhaust your worker pool and take the service offline. The exploit requires no special privileges and can be executed remotely.
The practical window may be narrowed by existing safeguards: many application servers (Puma, Unicorn) and reverse proxies (nginx, HAProxy) enforce default client body size limits, often 100 MB or less. But you cannot assume every environment has these protections, especially if your architecture moves large files or you’ve deliberately raised limits. Run bundle list | grep yajl or inspect your Gemfile.lock to confirm the installed version. If it’s 1.4.2 or lower, you’re vulnerable.
If you maintain a Ruby gem or application that vendors yajl-ruby
You carry an additional burden. Updating the gem dependency in your gemspec or Gemfile is necessary but not sufficient if you ship a statically compiled binary or have vendored the C source into your repository. You must rebuild the native extension from the patched source (1.4.3) and release a new version of your own gem or application. Use automated SCA tools and SBOM generators to confirm the vulnerable artifact is no longer present in your pipeline.
How we got here
yajl-ruby is a popular Ruby binding to YAJL (Yet Another JSON Library) that offers fast, streaming JSON parsing. Because it’s written in C, it skirts some of the memory safety guarantees of the Ruby VM. The vulnerability was discovered through responsible disclosure and reported to maintainer Brianmario, who published the GitHub advisory on April 19, 2023. The CVE was assigned shortly thereafter.
The root cause is a classic integer overflow: the growth logic repeatedly left-shifts a need value until it’s large enough, but on 32-bit platforms that shift can wrap into a small number before the allocation call. This pattern is well understood but hard to eradicate in native code. The maintainer issued an initial patch in version 1.4.2, but further testing revealed that it could still cause an infinite loop under certain edge cases, so version 1.4.3 became the canonical fix. Major Linux distributions, including Debian and Fedora, have backported the patch into their packaged Ruby gems.
What to do now
- Find every instance of yajl-ruby in your environment. Check
Gemfile.lockfiles, deployed container images, and any dependencies that might pull in the gem transitively. Usebundler-audit, Dependabot, or your SCA scanner to flag affected versions (≤1.4.2). - Patch to 1.4.3 immediately. Update your Gemfile constraint and run
bundle update yajl-ruby. If you consume yajl-ruby through an OS package (e.g.,ruby-yajlon Debian), apply the vendor’s security patch. Rebuild and redeploy your application. - Rebuild any statically linked or vendored binaries. If you compile the C extension into a standalone binary or include the gem’s source in your repo, the host package update won’t reach the embedded code. Re-run the build process against the fixed gem version and verify with
gem contents yajl-ruby. - If you can’t patch right away, apply immediate mitigations.
- Enforce strict request body size limits at the edge: configure nginx, Apache, or your Ruby web server to reject bodies larger than, say, 100 MB. For many applications, 10–50 MB is ample.
- Add rate-limiting rules or WAF signatures that block clients sending multiple oversized requests.
- Isolate the parser inside a forked process with tight memory limits (cgroups,ulimit), so a crash affects only that worker and is automatically restarted.
- Monitor for parse-related process crashes, abnormal OOM kills, or sudden spikes in worker restarts. - Verify the fix. After upgrading, run integration tests that simulate large JSON inputs—aim for sizes near your new limit—to confirm the application handles them gracefully. Re-scan your container images and SBOMs to ensure no yajl-ruby ≤1.4.2 remains.
Outlook
CVE-2022-24795 is a reminder that C extensions in high-level languages carry their own class of memory-safety bugs. While the patch for this specific overflow is straightforward, the incident reinforces the need for defensive parsing practices: always validate input sizes before handing them to native code, prefer streaming parsers that can abort early on oversized payloads, and isolate risky operations in dedicated processes with minimal privileges. Fuzz testing of C extensions should become a standard part of the Ruby gem development lifecycle.
The maintainer’s prompt response and the availability of the 1.4.3 fix mean that, for most teams, the path to safety is a simple dependency bump. The larger challenge—picking through legacy 32-bit builds and vendorized binaries—is a supply-chain hygiene problem that automated tooling can solve. Expect continued scrutiny of parsing libraries as more integer-overflow CVEs surface; staying current with dependency scanning and rebuild policies will be your best defense.