gemsafe

Decide before it runs.

Most breaches don't start with a supply-chain attack. They start with an ordinary gem that turns out to be exploitable the moment you depend on it. gemsafe reads what your dependencies do, and what your own code does, then decides before any of it ships.

What we find

A gem doesn't have to be malicious to breach you.

The headlines go to supply-chain attacks: a maintainer account stolen, a backdoor slipped into a release. Those are real, and they're rare. The common case is quieter. An ordinary gem, honestly published and widely used, that is exploitable on its own. Install it and its weaknesses are yours, reachable from your app's front door.

Scan the registry and this is most of what comes back. Not backdoors. Plain exploitable code that nobody flagged:

Request data into eval

A controller parameter, a request body, a cookie, reaching an eval or a shell. That's remote code execution, and anyone who can reach the endpoint has it.

Unsafe deserialization

YAML.load or Marshal.load on something a user controls. One crafted string becomes arbitrary code. It's the shape behind more than one Rails CVE.

Command injection

A shell command built by pasting a variable into a string. Give it a filename with a backtick in it and it runs commands nobody wrote.

Evaluated network data

A gem that fetches a response and evals it. Whoever controls that host, or the network to it, controls your process.

gemsafe follows untrusted input through the code. Across method calls, through the transforms in between, from the front door to the dangerous call. Then it flags the gems where that input ends up somewhere it shouldn't. The same analysis reads the code your own team wrote, because a flaw is a flaw whoever committed it.

You don't have to be targeted to be exploited.

Why Ruby

The attacks are real too, on plumbing defended more thinly than you'd expect.

Not a claim about the community. A claim about the plumbing. Every one of these is checkable in about a minute, and most Ruby teams have never had cause to look.

ControlnpmRubyGems
Lockfile integrity hashesalways on off by default
Packages carrying a signature~100% ~1.4%
Switch to skip install-time code--ignore-scripts none
Build provenance~40% of popular packages in progress

Meanwhile 2026 has been the worst year on record for gem-borne attacks: 136 trojanised gems in a single July campaign, self-propagating over SSH; tens of thousands of malicious uploads in May, enough that RubyGems suspended new account registration outright.

Every one of those attacks needed the same thing: code running at install time.

In Ruby that means native extensions, and Bundler gives you no way to turn them off. So gemsafe builds the switch that doesn't exist.

How it works

The decision happens while everything is still inert.

Resolution writes a lockfile without materialising anything, confirmed even for gems with native extensions. A .gem file is a plain tar. Downloading one, hashing it, and reading its metadata executes nothing.

That leaves a window where gemsafe knows exactly what is about to be installed and the gems have not yet been given a chance to act. Every check happens there. It is a Bundler plugin, hooked on before-install-all — which fires after resolution and before Bundler fetches, unpacks or compiles anything. So you keep typing bundle install, and a gem that fails a check is never downloaded.

Integrity, actually enforced

Bundler can verify checksums and does it well. It just doesn't by default, and a half-populated CHECKSUMS block looks protected while covering only some of your gems. gemsafe audits the whole chain.

A cooling-off period

Malicious versions are usually caught and pulled within hours. Declining to be first to install anything buys you that window, and needs no detection of any kind to work.

An allowlist for native code

Most projects need four or five gems that compile at install. Every other gem that wants to run extconf.rb is refused, and a new entry appearing in a pull request is exactly the signal you want.

A build with no way out

gemsafe fetches and verifies gems itself, so the install step needs no network at all. Compile in isolation and a hostile extension has nowhere to send anything.

Depth

The hard part is the code you can't read.

Pure-Ruby gems ship readable source. Precompiled ones don't. nokogiri 1.16.7 publishes eleven platform variants, ten of them carrying compiled binaries no reviewer opens. A backdoor in the Linux build is invisible to every developer on a Mac and fires only in production.

So we compare them. Across four consecutive releases of one variant:

Signal1.16.5 → 1.16.7→ 1.17.0
Imported symbols0 changed+6 / −4
Embedded hosts0 new0 new
Binary sizeidenticaln/a
Ruby source across all 11 variantsbyte-identical, 76 of 76 files

Baselines that tight make a new import or an unfamiliar hostname in a patch release impossible to miss. It is not proof. A careful attacker reuses the imports already there, which is why anything we can't positively clear is quarantined for review rather than waved through, and why the containment above runs regardless.

Detection gets worse as the attacker gets better. Containment doesn't.

Pricing

Priced on your dependencies, not your payroll.

Per-seat pricing charges you for hiring. But a fifty-person team and a five-person team running the same Rails app carry the same gems, the same transitive tree, and the same risk. Headcount is the wrong meter, so we don't use it.

Team

$199/ month · your whole organisation
  • Every engineer, every repository, every CI run
  • Every gem you depend on, read in full — source, data-flow and the compiled binaries nobody opens
  • Re-scanning a lockfile you've already scanned is free, permanently
  • 3,000 bonus analyses across your first 90 days, so onboarding an existing estate doesn't cost you

Business

$499/ month · your whole organisation
  • Everything in Team
  • Your own code, read the same way — the same data-flow analysis, on the code your team wrote
  • Private and internal gems
  • Enforcement in CI, SSO, and an audit log

Both tiers are flat and org-wide. There is no plan to outgrow and no usage to forecast — the difference between them is what gets analysed, not how much. Nothing ever stops scanning because of a quota. Self-hosted and air-gapped deployments are available; talk to us.

The deterministic checks are free forever. Checksum enforcement, cooling-off, the native-code allowlist and isolated installs run entirely on your machine, need no account, and cost us nothing to give away. Open source projects are free on request.

Get in touch →

Questions, or want a look for your team? That goes to hello@gemsafe.dev.