San Francisco — July 6, 2026. The Rust ecosystem crossed a quiet but consequential milestone this spring: crates.io now hosts more than 195,000 published crates, up from roughly 140,000 just two years ago, and the registry logs over 900 million downloads a week. Growth of that magnitude has made Cargo one of the fastest-expanding package ecosystems in software — and, per Safeguard Research Team's analysis of RustSec advisory data, crate metadata, and telemetry from customer SBOMs, one of the fastest-growing sources of new transitive-dependency risk in production codebases. In the twelve months ending June 2026, the RustSec Advisory Database recorded 214 new advisories affecting published crates — a 38% year-over-year increase — while the median time between a maintainer disclosing a vulnerability and a yanked/patched release stretched to 11 days, up from 7 days the prior year.
Rust's popularity has always carried an implicit safety pitch: a borrow checker that eliminates whole classes of memory bugs by construction. That pitch is still largely true at the language level. But Safeguard's data shows the ecosystem around the language is behaving like every other package ecosystem before it — Cargo is accumulating the same supply chain liabilities that have plagued npm and PyPI, just a few years behind the curve. This report breaks down what changed in the last year, where the risk is concentrated, and what security teams shipping Rust binaries should be watching.
The Shape of the 2026 Advisory Data
Of the 214 advisories tracked over the trailing twelve months, Safeguard's classification of RustSec entries breaks down roughly as follows:
- 41% — memory safety issues inside
unsafeblocks. Despite the borrow checker, nearly two in five advisories trace back to manualunsafecode — FFI boundaries, raw pointer arithmetic, and hand-rolled data structures — where Rust's guarantees are explicitly suspended. Crates wrapping C libraries (codecs, compression, crypto bindings) are disproportionately represented. - 23% — denial-of-service and resource exhaustion. Unbounded recursion in parser crates, unchecked allocation sizes in deserialization paths (particularly
serde-adjacent formats), and regex crates vulnerable to catastrophic backtracking or ReDoS-style input. - 17% — logic and cryptographic flaws. Timing side channels in constant-time crypto implementations, incorrect nonce reuse in AEAD wrappers, and authentication bypass bugs in web-framework middleware crates.
- 11% — malicious or compromised packages. Typosquats, dependency-confusion attempts, and at least four incidents where a previously legitimate crate's maintainer account was taken over and a malicious version was published before detection.
- 8% — unmaintained/abandoned crates flagged after the RustSec team determined no active maintainer would ship a fix, pushing consumers toward forks or replacements.
The malicious-package category is the one moving fastest in relative terms. Safeguard's telemetry recorded typosquat publications targeting popular crates — patterns mimicking serde, tokio, rand, and openssl-adjacent naming — at nearly triple the rate observed two years prior. crates.io's own abuse-response team has gotten faster at yanking these, with median takedown time now under six hours, but "median" hides the tail: several packages sat live for over a week before removal, long enough to be pulled into CI caches and vendored dependency trees that don't re-resolve on every build.
Case Study: The async-fs-util Incident
The most instructive incident of the period involved a crate we're calling async-fs-util for reporting purposes (advisory details are publicly tracked under its RustSec ID). In February 2026, a maintainer account with publish rights to a moderately popular async filesystem helper — pulled in transitively by several web-framework and CLI-tool crates — was compromised via a reused, previously-breached password with no MFA enabled. The attacker published a patch-version bump containing a build script (build.rs) that exfiltrated environment variables and ~/.cargo/credentials.toml contents to an attacker-controlled endpoint during compilation, not at runtime.
This detail matters: build.rs scripts execute at build time, with the full permissions of the developer or CI runner invoking cargo build. Unlike a runtime vulnerability that requires the vulnerable code path to actually execute, a malicious build script runs unconditionally, on every machine that compiles the crate — including CI pipelines that may hold cloud credentials, signing keys, or registry publish tokens. The compromised version was live for approximately 34 hours before a maintainer with revoked access noticed and alerted the RustSec team. Safeguard's estimate, based on crates.io's own download counters for the affected version window, puts potential exposure at several thousand distinct build environments.
The incident reinforced a pattern Safeguard has now seen across three ecosystems in eighteen months: build-time supply chain compromise, not runtime exploitation, is becoming attackers' preferred path into CI/CD, because it bypasses application-layer defenses entirely.
Why Transitive Depth Keeps Growing
Cargo's flat, additive dependency model makes it unusually easy for small crates to compound into deep trees. Safeguard's SBOM ingestion data across customer Rust projects shows a median of 187 total dependencies (direct plus transitive) for a typical mid-sized service binary, versus 34 direct dependencies declared in Cargo.toml. That means the average team is directly aware of roughly 18% of what actually ships in their binary. Of the 214 advisories tracked this year, 61% affected crates that appeared only as transitive dependencies in the projects where Safeguard observed exposure — meaning the affected crate was never explicitly chosen or reviewed by the engineering team running it.
Feature-flag proliferation compounds this. Popular crates like tokio, serde, and reqwest ship dozens of optional features, and default-feature inclusion frequently pulls in code paths (TLS backends, compression libraries, platform-specific FFI shims) that a given application never actually exercises but still compiles and ships. This is precisely where vulnerability counts diverge from vulnerability exposure: a crate can appear in an SBOM and trigger an advisory match without a single reachable code path ever executing the vulnerable function.
The Detection Gap
Traditional SCA tooling flags a vulnerable crate the moment its version string matches an advisory range, regardless of whether the vulnerable function is ever called. Across the Rust projects in Safeguard's dataset, an average of 58% of crate-level CVE matches corresponded to code that was never reachable from the application's actual call graph — either because the affected function lived behind a disabled feature flag, an unused module, or a code path gated by configuration the application never enables. Security teams chasing every match in that population are spending the majority of their remediation cycles on findings with no real-world exploitability, which is the single biggest driver of alert fatigue and patch backlog we see in Rust shops today.
What to Watch Through the Rest of 2026
Three trends are worth tracking heading into H2 2026: first, crates.io's continued rollout of mandatory MFA for publishers of high-download crates should reduce account-takeover incidents like async-fs-util, but adoption is voluntary until the policy's enforcement deadline later this year. Second, build.rs script auditing remains almost entirely absent from mainstream CI pipelines — very few organizations sandbox or restrict what build scripts can access, leaving the exact vector used in February's incident wide open industry-wide. Third, the advisory backlog for unmaintained crates is growing faster than the ecosystem is replacing them, meaning more production binaries will be running dependency code with no active maintainer to ship a fix when the next flaw surfaces.
How Safeguard Helps
Safeguard is built for exactly this gap between what a crate-level scanner flags and what actually matters. Our SBOM generation and ingest pipeline builds a precise, feature-flag-aware dependency graph for Cargo projects — direct and transitive — so teams can see the full 187-dependency reality instead of the 34 they declared. Griffin AI, our reachability engine, traces call paths from application entry points through the dependency tree to determine whether a flagged vulnerable function in a crate like the ones cited above is actually invocable in your build, cutting through the 58% of matches that carry no real exploitability and letting teams prioritize the fraction that do. For the incidents that are real — a compromised maintainer account, an unpatched memory-safety bug in an unsafe block your binary actually reaches — Safeguard's auto-fix PRs open a scoped, reviewable pull request with the patched version pinned and the change explained, so remediation ships in minutes rather than sitting in a backlog. Together, reachability-informed prioritization and automated remediation let security and platform teams keep pace with an ecosystem adding advisories 38% faster than it did a year ago, without adding headcount.