Open Source Security

Rust Supply Chain Security: How crates.io Stacks Up Against npm and PyPI

Rust's crates.io registry has design advantages for supply chain security, but it's not immune. Here's an honest assessment of the Rust ecosystem.

Shadab Khan
Threat Intelligence
6 min read

Rust's crates.io registry occupies an interesting position in the software supply chain security landscape. With approximately 95,000 crates (packages) as of September 2022 — a fraction of npm's 2 million or PyPI's 400,000 — the Rust ecosystem is smaller but growing rapidly. And several design decisions in Rust and crates.io provide inherent supply chain security advantages that larger ecosystems lack.

But smaller and better-designed doesn't mean immune. Here's an honest look at where Rust's supply chain stands.

Structural Advantages

No Arbitrary Code Execution During Installation

This is the big one. When you run cargo add or cargo build, Cargo (Rust's package manager) does not execute arbitrary code during dependency installation. Compare this to:

  • npm: Runs lifecycle scripts (preinstall, postinstall) that can execute any code
  • PyPI: Runs setup.py during installation, which can contain any Python code
  • RubyGems: Runs extension build scripts that can execute native code

In the Rust ecosystem, a malicious crate would need to include code that the downstream project actually compiles and invokes. This significantly narrows the attack surface compared to ecosystems where install alone is sufficient for exploitation.

There is one exception: build scripts (build.rs). Crates can include a build script that runs at compile time to generate code, link native libraries, or perform other build tasks. Build scripts can execute arbitrary code, so they do represent an attack surface — but they're visible in the crate source and can be audited.

Strong Type System and Memory Safety

Rust's type system and borrow checker catch entire classes of bugs at compile time that would be vulnerabilities in C/C++. Buffer overflows, use-after-free, and data races — the bread and butter of memory corruption exploits — are prevented by the language itself in safe Rust code.

This doesn't eliminate vulnerabilities, but it raises the bar for creating exploitable ones. A malicious crate author would need to use unsafe blocks to introduce memory-corruption vulnerabilities, and unsafe usage is visible and auditable.

Cargo.lock for Reproducible Builds

Rust projects use Cargo.lock to pin exact dependency versions, including transitive dependencies. This is generated automatically and committed to version control for binary projects. The lockfile ensures that cargo build produces the same result regardless of when or where it's run, preventing version substitution attacks.

Crate Yanking, Not Deletion

When a crate version is removed from crates.io, it's "yanked" — it won't be used for new resolutions but remains available for projects that already reference it in their Cargo.lock. This prevents the kind of left-pad incident that affected npm in 2016, where deleting a package broke thousands of downstream builds.

Known Vulnerabilities and Incidents

The Rust ecosystem has not been exempt from supply chain incidents:

Crate Typosquatting

Researchers have identified typosquatting attempts on crates.io, though at a lower volume than npm or PyPI. In May 2022, ReversingLabs found several suspicious crates that appeared to be typosquats of popular packages. The relatively small size of the ecosystem makes manual review more feasible, but as crates.io grows, this becomes harder.

The rustdecimal Incident

In May 2022, the CratesFyi team discovered that the rustdecimal crate was a typosquat of the legitimate rust_decimal crate. The malicious version included code in its build.rs that downloaded and executed a payload from a remote server. This incident demonstrated that build scripts are a viable attack vector in the Rust ecosystem.

RustSec Advisory Database

The RustSec project maintains a database of security advisories for Rust crates. By September 2022, the database contained over 500 advisories. While most were for legitimate bugs rather than malicious packages, the volume of advisories highlights that Rust crates are not immune to vulnerabilities.

Gaps and Challenges

Build Script Attack Surface

Build scripts (build.rs) can execute arbitrary code at compile time, and they represent the primary supply chain attack vector in Rust. A malicious build.rs can download and execute payloads, exfiltrate environment variables (including CI/CD secrets), or modify the compilation process.

While build scripts are visible in the crate source, developers rarely audit the build scripts of their dependencies — especially transitive dependencies.

Unsafe Code in Dependencies

Crates that use unsafe code introduce risks that Rust's safety guarantees don't cover. The cargo-geiger tool can identify unsafe usage in your dependency tree, but it's not part of the default workflow.

No Package Signing (Yet)

As of September 2022, crates.io did not support package signing. Published crates are uploaded over TLS, and the registry verifies the uploader's API token, but there's no cryptographic signature binding a crate to its publisher or source code. The crate you download is the one the registry serves, but there's no independent verification mechanism.

Limited MFA Enforcement

crates.io supported MFA for publisher accounts but didn't mandate it. High-value crates — those with many dependents — could be compromised through account takeover without the additional protection of MFA.

Dependency Tree Depth

While Rust's dependency trees tend to be shallower than npm's, they're still significant. A typical Rust project might have 100-300 transitive dependencies. Each dependency is a trust relationship, and auditing the entire tree is impractical without tooling.

Tools for Rust Supply Chain Security

cargo-audit

Checks your Cargo.lock against the RustSec Advisory Database. It's the Rust equivalent of npm audit and should be part of every CI/CD pipeline.

cargo-deny

A more comprehensive tool that checks dependencies for:

  • Known vulnerabilities (via RustSec)
  • License compliance
  • Banned crates (crates you've explicitly prohibited)
  • Duplicate dependencies
  • Crates from untrusted sources

cargo-vet

A newer tool (released in 2022 by Mozilla) that enables organizations to track and share audits of their dependencies. Teams can record that specific crate versions have been reviewed, and those audits can be shared across organizations.

cargo-geiger

Scans your dependency tree for unsafe code usage, helping you understand which dependencies could potentially contain memory-safety vulnerabilities.

cargo-crev

A distributed code review system for Rust crates. Developers can publish reviews of crate versions, and cargo-crev aggregates these reviews based on a web of trust.

Recommendations for Rust Projects

  1. Run cargo-audit in CI. Every build should check for known vulnerabilities.
  2. Use cargo-deny for policy enforcement. Define and enforce rules about which crates are acceptable.
  3. Audit build scripts of new dependencies. Before adding a dependency, check whether it has a build.rs and what it does.
  4. Monitor for typosquats. If you maintain popular crates, watch for similarly-named crates.
  5. Use cargo-vet for dependency auditing. Track which dependencies have been reviewed and share audits with the community.
  6. Pin to specific versions. Use Cargo.lock and commit it to version control.
  7. Minimize dependency count. Rust's standard library is more comprehensive than many languages. Use it before reaching for a crate.

How Safeguard.sh Helps

Safeguard.sh supports the Rust ecosystem alongside npm, PyPI, and other package registries. Our platform generates SBOMs for Rust projects, monitors crates for known vulnerabilities and malicious packages, and provides policy enforcement across your Rust dependency tree. With support for cargo-audit integration and continuous monitoring of the crates.io registry, Safeguard.sh ensures that Rust's inherent security advantages are complemented by comprehensive supply chain visibility and governance.

Never miss an update

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