CVE-2026-27820 is a critical buffer overflow (CVSS 9.8) in the Ruby zlib gem's Zlib::GzipReader. A function that pushes bytes back into the buffer does not check capacity before moving data. The fixes are 3.0.1, 3.1.2 and 3.2.3. Upgrade the gem on the line you use. The record does not mark it as exploited in the wild.
What's affected
The zlib gem for Ruby. The NVD record lists 3.0.0 and below, 3.1.0, 3.1.1, 3.2.0 and 3.2.1 as affected. The GitHub advisory words it as 3.2.2 or lower. Treat every version below the fixed one on your line as affected.
- Fixed on the 3.0 line: 3.0.1
- Fixed on the 3.1 line: 3.1.2
- Fixed on the 3.2 line: 3.2.3
Zlib is also bundled with Ruby itself as a default gem, so check the Ruby release notes or your distributor if you rely on the bundled copy.
How to check if you're exposed
Check which zlib gem version your application loads.
bundle list | grep zlib
gem list zlib
ruby -rzlib -e 'puts Zlib::VERSION'
The first command shows what Bundler resolved for the project. The second lists installed gem versions. The third prints the version of the zlib binding Ruby loads at runtime, which is the one that matters. Check inside containers and CI images too.
Then search your code for Zlib::GzipReader, which is the class named in the record. Code that never reads gzip data through it is less exposed.
What to do now
- Upgrade the zlib gem to 3.0.1, 3.1.2 or 3.2.3, whichever matches your current line, or later.
- Run bundle update zlib, commit the lockfile change and rebuild images.
- If you use the zlib copy bundled with Ruby, move to a Ruby release that includes the fixed gem, or install the gem version explicitly.
- Treat gzip input from outside your network as untrusted until the fix is deployed.
- Scan your Gemfile.lock for other outdated gems at https://gold.safeguard.sh/scan.
Why it matters
The record says the zstream_buffer_ungets function prepends caller-provided bytes ahead of output the stream has already produced, then moves the existing data without making sure the backing Ruby string has enough capacity. When the buffer length exceeds capacity, memory is corrupted. NVD classifies the flaw as CWE-120 (Buffer Copy without Checking Size of Input) and CWE-131 (Incorrect Calculation of Buffer Size).
Compression code handles data from outside, which is why bugs in it carry high scores. Reachability analysis helps here: it shows whether your code actually calls the vulnerable GzipReader path, so you can rank this fix against others.
How the bug arises
The record points at one function, zstream_buffer_ungets. It pushes bytes back in front of data the stream already produced. To do that it moves existing data inside a Ruby string, and the record says it does not first make sure the string has enough room. When the length exceeds the capacity, the move writes memory it should not.
This is a familiar pattern in native extensions. Ruby code is memory safe, while the C code under it is not, so bounds errors in extensions have the same effect as in any C program.
Finding every copy
Ruby applications can carry several copies of a gem. There is the version in the Gemfile.lock, there may be a version bundled with the Ruby interpreter, and there may be copies baked into container images or vendored directories. Check each environment where the application runs, not only your laptop.
bundle exec ruby -rzlib -e 'puts Zlib::VERSION'
Running the check through bundle exec shows the version the application would actually load.
Prioritising
Use reachability to decide urgency. If your code reads gzip streams from outside, for example uploads, downloads or HTTP bodies handled through GzipReader, move first. If the gem is present but the class is never used, schedule the update with your normal cadence.
After upgrading
Rebuild images, redeploy and re-run the version check in production. Add the gem to your continuous monitoring so a future advisory is flagged without a manual search.
Why compression libraries keep appearing
Libraries that read compressed data take input of unknown size and shape, and they mix buffer handling with logic for streams. That combination produces a steady flow of memory bugs, and the data often comes from outside the trust boundary. Keeping them current, and watching them in your inventory, is a cheap habit that pays off every time one of them has an advisory.
Writing it up for your team
A short note is enough. Name the gem, the three fixed versions, the places you checked and the owner for each application. Include the command that confirms the version so the next person can repeat it. Add the gem to the watch list that tells you about new advisories.
Try it yourself
Not every vulnerable gem is reachable in your application. This demo shows how reachability narrows a long list down to what matters.
Click through it at your own pace, or open it full screen.
Quick check
Is Ruby itself affected?
The record covers the zlib gem. Because zlib ships as a default gem, check the Ruby release or your distributor for how the fix reaches the bundled copy.
Which version should I pick?
The one that matches your line: 3.0.1, 3.1.2 or 3.2.3.
Sources
Last reviewed: 19 October 2026.