A malicious gem usually looks like a normal one: a plausible name, a short history and code that runs at install or load time. The signs are a new or changed owner, an unexpected native extension or install hook, and files that do not match the source repository. If you installed one, rotate secrets first, then yank, report and rebuild.
What are the warning signs?
No single signal proves anything, so combine them.
- A name close to a popular gem, or a gem that claims to be the official client for a service but is published by an unknown account.
- A new version after a long quiet period, especially one that changes owners, adds a native extension or adds files that are not in the public repository.
- Install-time behaviour. Gems with native extensions compile code during installation, so any build script is code execution on the machine running bundle install.
- Network calls or environment variable reads in code that has no reason to make them.
The RubyGems security guide gives one practical way to look: authors should review packaged files with gem unpack before pushing, and so can you before trusting. Unpack the gem and compare it to the tagged source.
How do you reduce the chance of installing one?
The same guide lists several controls that need no new tools.
Bundler records a CHECKSUMS section in new lockfiles and verifies each gem on install. Existing lockfiles can be updated with bundle lock --add-checksums. That stops a gem file changing under a version you already approved.
A cooldown setting excludes versions published within a set number of days, for example bundle config set cooldown 7, so you do not take a release before others have had time to vet it. A new malicious version has the shortest useful life when nobody installs it on day one.
For internal gems, pin them to their source with source blocks, which prevents a public gem with the same name from substituting. Run bundler-audit in CI to check Gemfile.lock against the ruby-advisory-db, which catches known advisories but not unreported malware.
On the publishing side, the guide calls multi-factor authentication the most effective defence against account takeover, and prefers WebAuthn with a security key or passkey.
What do you do if a bad gem was installed?
Order matters.
- Treat the machine or build as exposed. Anything the install could read, such as environment variables, tokens and SSH keys, should be considered copied. Revoke and rotate those first. RubyGems states this for the maintainer case too: if a secret was shipped, revoke it first, then yank the version.
- Identify where it ran: developer laptops, CI runners, container builds. Search lockfiles in every repository for the gem and version.
- Remove it and rebuild from a clean lockfile with checksums. Delete caches on build machines.
- Report it. The guide says to email security@rubygems.org or use HackerOne for malicious gems, and not to open a public issue.
- Write a short timeline for your records, including which credentials you rotated and when.
What if you maintain a gem that was hijacked?
Yank the affected versions immediately and report to security@rubygems.org. The RubyGems docs note that yanking removes the version from the index and the gem file, but that webhooks and mirrors mean several hundred services get pinged when new gems are pushed, so a copy may already exist elsewhere. Reset any sensitive data right away rather than relying on the yank.
What to do
- Commit lockfile checksums and verify them in CI.
- Set a cooldown for non-security updates.
- Pin internal gems to a source block.
- Run bundler-audit on every build.
- Require MFA with WebAuthn on every publishing account.
- Write a runbook for the response steps above before you need it. Safeguard's free scan at gold.safeguard.sh/scan can help you review a dependency list, up to 100 dependencies in the browser.
Quick check
Does yanking a gem remove it everywhere?
No. Mirrors and webhooks mean copies may exist. Rotate any exposed secrets first, then yank.
Does bundler-audit detect new malware?
Not on its own. It checks your lockfile against known advisories, so a fresh unreported malicious version will not appear.
Sources
Last reviewed: 18 October 2026.