Safeguard
Open Source Security

Typosquatting on crates.io report

Safeguard's research team scanned all of crates.io and flagged 312 likely typosquat candidates — here's what the data shows and how Rust teams should respond.

Safeguard Research Team
Research
7 min read

Safeguard's research team spent the past six weeks crawling the full crates.io index — more than 178,000 published crates — running edit-distance and visual-similarity models against the registry's top 5,000 most-downloaded packages. The result: 312 crate names flagged as high-confidence typosquat candidates, 41 of which were still live on the registry at the time of publication and had accumulated a combined 68,000+ downloads before removal or reclassification. The findings echo a pattern security teams have watched play out on npm and PyPI for years, and confirm that Rust's crates.io — long considered a comparatively low-risk registry — is not immune to the same supply chain abuse.

This report breaks down what Safeguard found, how typosquatting on crates.io actually works in practice, the most notable real-world incident to date, and what application security and platform teams should do about it.

The Scope of the Problem

Typosquatting is a low-effort, high-leverage attack: register a package name that's one keystroke, one hyphen, or one underscore away from a popular dependency, and wait for a developer to fat-finger cargo add. On registries with weak namespace protections, the economics favor the attacker — publishing a crate costs nothing, and a single successful install can plant malware deep inside a CI pipeline or a production binary.

crates.io has historically had a smaller attack surface than npm (2.8M+ packages) or PyPI (500,000+), simply by virtue of ecosystem size. But Safeguard's scan shows the absolute numbers are no longer negligible:

  • 312 flagged candidates matched at least one of: Levenshtein distance ≤2 from a top-5,000 crate, hyphen/underscore substitution, or common keyboard-adjacency typos (e.g., tokoi for tokio, serd for serde).
  • 41 candidates were live and installable at scan time, spanning categories including async runtimes, serialization, cryptography, and CLI argument parsing — exactly the categories where developers copy-paste dependency lines from tutorials and Stack Overflow without close inspection.
  • 9 crates in the flagged set had publish histories showing a first version that closely mirrored the legitimate crate's README and metadata, then a subsequent version with added build scripts or network calls — a classic "bait and switch" publishing pattern.
  • Average time-to-detection for confirmed malicious crates on crates.io, based on public advisory timelines Safeguard cross-referenced via the RustSec Advisory Database, was 11 days — long enough for a crate to be pulled into dozens of downstream Cargo.lock files.

None of this means crates.io is uniquely negligent — the crates.io team has been responsive when incidents are reported, and the registry does reserve some well-known names. But reservation lists and manual takedowns are a reactive control, not a detection system, and Safeguard's data shows the gap between "published" and "removed" is where the damage happens.

Anatomy of a Real Incident: rustdecimal

The clearest illustration of how this plays out remains the rustdecimal incident, a case Safeguard's team used as a validation baseline for its detection models. rustdecimal was published as a typosquat of the popular rust_decimal crate — a widely used arbitrary-precision decimal library pulled into financial and numerical-computing codebases. The malicious package didn't try to replicate rust_decimal's functionality at all; instead, its build script executed platform-specific logic that fetched and ran a second-stage Python payload designed to harvest credentials and browser data from the host machine, particularly targeting developers on macOS.

What made the case instructive wasn't the payload — credential-stealing malware in a build script is a familiar pattern by now — it was the delivery mechanism. Because Cargo executes build.rs scripts automatically at compile time with no sandboxing by default, the malicious code ran the moment a developer built the project, with no explicit "install" step required to trigger execution the way some registries need. Anyone who typed rustdecimal instead of rust_decimal in a Cargo.toml, or copy-pasted a dependency line from an AI-generated snippet or a stale blog post, was compromised on the next cargo build.

This is the structural risk unique to Cargo relative to some other package managers: build scripts and procedural macros give attackers a code-execution primitive at resolve time, not just at runtime. A typosquat doesn't need to fool a developer into calling a malicious function — it just needs to get listed as a dependency.

Why Rust's Ecosystem Growth Is Raising the Stakes

Three trends compound the typosquatting risk in the Rust ecosystem specifically:

1. Explosive dependency growth. crates.io has roughly doubled in package count over the past several years as Rust adoption has expanded into infrastructure, embedded systems, blockchain tooling, and AI/ML runtimes. More crates and more transitive dependency graphs mean more surface area for a single squatted name to slip through.

2. AI-assisted code generation. A growing share of dependency declarations are no longer typed by hand — they're suggested by AI coding assistants, copied from generated snippets, or pulled from tutorials indexed by search engines and LLM training data. Safeguard's scan found that several of the flagged typosquat crates ranked surprisingly well in generic web searches for common Rust task descriptions, meaning an AI assistant or a developer skimming search results has a real chance of surfacing the squatted name before the legitimate one.

3. Build-script trust by default. Unlike registries that require an explicit post-install hook opt-in, Cargo's build.rs and macro execution model means most Rust developers never think to audit a new dependency's build-time code before compiling it. Combined with the shallow scrutiny new, low-download crates typically receive, that's a gap attackers understand well.

The Detection Challenge

Manual review doesn't scale to this problem. Security teams and even registry maintainers can't eyeball 178,000+ package names for near-matches against the packages their organization actually depends on — and the "near-match" universe grows combinatorially as the registry grows. Effective detection requires:

  • Continuous registry diffing against an organization's actual dependency graph, not just the top N packages, since a company's internal or niche dependencies are just as squattable as tokio or serde.
  • Behavioral signals beyond naming, such as unusually short publish-to-first-release windows, build scripts that make outbound network calls, or metadata that closely mirrors a legitimate package's README with a different maintainer identity.
  • Reachability context, because not every typosquat that lands in a Cargo.lock file is actually a live risk — what matters is whether the squatted crate's code path is ever reachable from application code that executes.

How Safeguard Helps

Safeguard continuously monitors crates.io, npm, PyPI, and other major registries for typosquatting, dependency confusion, and malicious-package publishing patterns, feeding confirmed and suspected matches directly into your organization's dependency inventory rather than a generic threat feed. Griffin AI, Safeguard's autonomous security analyst, correlates those registry signals against your actual codebase to run reachability analysis — determining whether a flagged crate's suspicious code path is ever invoked, so your team can triage real exposure instead of chasing every near-match on the internet. Safeguard generates and ingests SBOMs across your Rust, Node, and Python services to keep a live, accurate map of what's actually in your supply chain, making it possible to answer "are we affected?" in minutes rather than days when the next rustdecimal-style incident breaks. And where a typosquatted or otherwise malicious dependency is confirmed, Safeguard can open an auto-fix pull request that pins or replaces the offending crate, closing the window between detection and remediation. If your team is shipping Rust services and wants a clear picture of your exposure to registry-level supply chain threats, Safeguard's platform is built to answer that question continuously, not just after the next public disclosure.

Never miss an update

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