Safeguard
Open Source Security

RubyGems 2019 Multi-CVE Disclosure: Directory Traversal v...

CVE-2019-8320 let malicious RubyGems packages delete arbitrary directories via symlinked gem decompression. Here's the impact, timeline, and how to remediate it.

Aman Khan
AppSec Engineer
8 min read

CVE-2019-8320 is a directory traversal vulnerability in RubyGems, the default Ruby package manager, that lets a malicious gem delete arbitrary directories on the machine that installs or uninstalls it. The flaw lives in how RubyGems handled gem decompression: before writing a package's files to disk, older versions of RubyGems would blindly delete the destination path first — and if an attacker had replaced that path with a symlink, RubyGems would follow it and delete whatever the symlink pointed to instead. Because gem install and gem uninstall are frequently run with elevated privileges, the practical impact ranged from broken development environments to full system compromise on predictable paths like /tmp or /usr.

CVE-2019-8320 was one of six RubyGems CVEs disclosed together in a single coordinated advisory in March 2019, and it remains a useful case study in why "just decompress the tarball" is never as simple as it sounds — and why software supply chain teams need visibility into exactly which package manager versions are running across their fleet.

What CVE-2019-8320 actually does

RubyGems packages (.gem files) are themselves tar archives containing metadata plus a nested, gzip-compressed tarball of the actual source files. When you run gem install or gem uninstall, RubyGems has to unpack that structure onto disk, creating directories and writing files as it goes.

The vulnerable code path had a subtle but serious mistake: before creating a target directory or writing a target file during gem decompression, RubyGems would first delete whatever already existed at that path, on the assumption that it was cleaning up a stale artifact from a previous install. It did not check whether that path was actually a symlink pointing somewhere else entirely.

An attacker who could get a victim to install (or uninstall) a crafted gem could therefore embed a symlink inside the package pointing at a sensitive directory — say, /etc, /usr, or a project's .git folder — and RubyGems would happily delete the real target when it "cleaned up" that path before extraction. Because gem installation is commonly performed as root or via sudo, and because directory layouts on most systems are highly predictable, this gave attackers a realistic path to destructive, system-wide data loss rather than just a theoretical directory-traversal bug confined to a sandbox.

This is a classic CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) issue, but it's worth noting the trigger here wasn't ../../ path segments in a filename — it was symlink resolution during gem decompression, a variant that's easy to miss in code review because the destination path itself looks perfectly legitimate.

Affected versions and components

  • Component: RubyGems (the package manager bundled with the Ruby interpreter, not a specific gem)
  • Affected versions: RubyGems 2.7.6 through 3.0.2
  • Fixed versions: RubyGems 2.7.9 and 3.0.3 (and later releases)
  • Affected Ruby interpreter releases: because RubyGems ships inside Ruby itself, any Ruby installation bundling one of the vulnerable RubyGems versions was exposed until it was upgraded

Because RubyGems is not something most Ruby developers manage as a discrete dependency — it comes bundled with the interpreter — the realistic remediation path was either running gem update --system to pull a patched RubyGems release, or upgrading the Ruby interpreter itself to a release that bundled a fixed version.

CVSS severity and exploitability context

NVD scores CVE-2019-8320 as CVSS v3.0 base score 7.4 (High), with the vector AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H — network attack vector, high attack complexity, no privileges or user interaction required, no confidentiality impact, but high integrity and availability impact, reflecting the fact that this is a destructive file/directory-deletion primitive rather than an information disclosure issue. The older CVSS v2 scoring for the same finding came in even higher, at 8.8.

CVE-2019-8320 does not appear on CISA's Known Exploited Vulnerabilities (KEV) catalog, and there's no widely reported evidence of large-scale exploitation in the wild — its practical exploitation still requires a victim to install or uninstall a specifically crafted malicious gem, which narrows the realistic attack surface compared to a fully remote, unauthenticated bug. That said, "getting a developer to install a gem" is precisely the threat model that has repeatedly played out in real RubyGems supply chain incidents (typosquatting, dependency confusion, compromised maintainer accounts), which is exactly why a bug that turns "install this package" into "delete arbitrary directories on this host" deserves to be taken seriously rather than dismissed because it isn't remotely triggerable on its own.

Timeline

  • March 5, 2019 — The RubyGems project and Ruby core team jointly published a coordinated security advisory covering six vulnerabilities discovered in RubyGems: CVE-2019-8320 through CVE-2019-8325. CVE-2019-8320 (the directory-traversal/symlink deletion issue) was credited to researcher ooooooo_q.
  • March 5, 2019 — RubyGems 3.0.3 and 2.7.9 were released containing fixes for all six vulnerabilities, alongside guidance to run gem update --system to pick up the patched release.
  • Follow-up Ruby patch releases — Ruby maintainers subsequently shipped updated Ruby interpreter versions bundling the fixed RubyGems so that users who manage Ruby (rather than RubyGems) as their upgrade unit were also covered.
  • June 2019 — NVD published its formal CVE-2019-8320 record with CVSS scoring, several months after the original coordinated disclosure — a reminder that NVD publication dates often lag the actual vendor advisory and patch availability by a meaningful margin.

Remediation steps

  1. Update RubyGems directly. Run gem update --system to pull the latest RubyGems release; confirm the installed version is 2.7.9, 3.0.3, or newer with gem --version.
  2. Upgrade the Ruby interpreter where RubyGems is bundled. If you manage Ruby via a version manager (rbenv, rvm, asdf) or system packages, move to a Ruby release that bundles a patched RubyGems rather than patching RubyGems in isolation, since some environments re-bundle RubyGems on interpreter upgrade.
  3. Audit CI/CD and container base images. Docker base images, CI runners, and build agents frequently pin old Ruby/RubyGems versions for reproducibility. Inventory every image and pipeline that installs gems and confirm none are still running RubyGems 2.7.6–3.0.2.
  4. Avoid running gem install/gem uninstall as root where possible. Since the impact of CVE-2019-8320 is amplified by privilege level, scoping gem operations to a non-root user (or a container with limited filesystem access) reduces blast radius even on unpatched systems.
  5. Treat gem decompression as untrusted input. More broadly, this CVE is a good prompt to review any internal tooling that unpacks third-party archives (gems, tarballs, zip files) for the same symlink-following mistake — it's a recurring vulnerability pattern, not one unique to RubyGems.
  6. Verify third-party and vendored dependencies. If you vendor gems or maintain internal mirrors, confirm the packages you're serving were built and repackaged with a patched RubyGems, since a compromised build pipeline using vulnerable tooling could reintroduce the same directory traversal.

How Safeguard Helps

CVE-2019-8320 is a reminder that software supply chain risk isn't limited to the packages you consume — it extends to the package manager doing the consuming. RubyGems, npm, pip, and every other package manager parse and decompress untrusted archives on your behalf, and a single mishandled symlink or path segment turns "install a dependency" into "attacker-controlled filesystem operation."

Safeguard helps engineering and security teams close exactly this kind of blind spot:

  • Continuous SBOM and toolchain inventory — Safeguard maintains a live inventory of the language runtimes and package managers in use across your repositories, containers, and build pipelines, so you know immediately which of your Ruby environments are still running a RubyGems version affected by CVE-2019-8320 or similar issues, instead of relying on tribal knowledge.
  • CVE and vulnerability correlation — Rather than surfacing raw CVE feeds, Safeguard maps disclosed vulnerabilities like CVE-2019-8320 directly to the affected components in your environment, cutting through noise so security teams can prioritize the RubyGems (or Ruby interpreter) versions that actually need to move.
  • Build pipeline and CI/CD visibility — Because CVE-2019-8320 disproportionately affects CI runners and container base images that pin old interpreter versions for reproducibility, Safeguard's monitoring of build pipelines flags stale, vulnerable toolchains before they ship into production artifacts.
  • Policy enforcement for package manager versions — Safeguard lets teams codify minimum-version policies for critical tooling (RubyGems, npm, pip, and beyond) and enforce them at build time, so a regression to a vulnerable RubyGems release in a new image or environment gets caught automatically rather than discovered after an incident.
  • Supply chain integrity monitoring — Beyond this specific CVE, Safeguard's broader focus on software supply chain security means the same class of bug — untrusted archive decompression, symlink handling, path traversal — is something we track across the entire dependency graph, not just RubyGems, so similar issues in other ecosystems don't slip through unnoticed.

Package managers are trusted infrastructure, and vulnerabilities like CVE-2019-8320 show what happens when that trust is misplaced even briefly. Keeping RubyGems current is the direct fix; having continuous visibility into every toolchain version running across your organization is what keeps the next disclosure from becoming an incident.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.