THE LINUX FOUNDATION PROJECTS
Blog

Surfacing Security Advisories on crates.io: Bringing Vulnerability Data to the Point of Discovery

by Dirkjan Ochtman

When Rust developers evaluate a new dependency, the first place most of them go is crates.io — the official Rust package registry. There, they can quickly check metrics like download counts, the number of dependent crates, and the release history. However, one thing that has not been represented until recently is whether a crate has a history of (known) security vulnerabilities. That information lives elsewhere: in the RustSec advisory database, which can be consumed via tools like cargo-audit and cargo-deny.

With funding from Alpha-Omega through the Rust Foundation, I set out to change that. Crate pages on crates.io now include a Security tab that displays known vulnerabilities sourced from the RustSec advisory database. The tab is visible on every crate page, and when advisories affect the currently selected version, users can see at a glance what’s known before they add the dependency.

Why the Discovery Phase Matters

Most package registries surface vulnerability information after the fact. Developers install a package, then discover its issues through audit tools or CI checks — if those are configured at all. The dependency decision itself happens earlier, often informally, when someone is browsing crates.io and running cargo add.

This gap matters for the Rust ecosystem in particular. Rust’s culture of small, focused crates means that many projects accumulate a large number of dependencies. Each dependency is a trust decision, and the more dependencies a project has, the higher the chance that one of them carries a known vulnerability. Surfacing advisory data at the point of discovery doesn’t replace downstream audit tooling, but it might help deciding whether some crate makes for a good dependency for your project.

crates.io is one of the first major package registries to surface advisory data directly on package pages during the browsing and discovery phase.

The Path from RFC to Implementation

The work started with an RFC — RFC 3872, opened in late October 2025 — which proposed adding a Security tab to crate pages on crates.io.

Some feedback raised concerns about the optics of displaying advisory data from a third-party database (RustSec) on the official registry. Others worried that advisory counts could be misinterpreted as a quality signal — that popular, well-maintained crates would appear “worse” simply because they receive more scrutiny and have more reported issues. These are legitimate concerns, and the design reflects them: the Security tab presents factual information about known advisories without scoring or ranking crates.

With the RFC accepted, I began implementing the feature against the crates.io codebase. The initial PR landed on January 8, 2026, followed by a series of iterative improvements over the next few weeks.

What the Security Tab Shows

The Security tab displays advisories from the RustSec database that affect the crate. For each advisory, users see:

  • The advisory identifier (e.g. RUSTSEC-2024-XXXX) and any aliases (such as CVE identifiers)
  • A short description of the vulnerability
  • The affected version ranges, so users can tell whether the specific version they’re looking at is impacted
  • CVSS vectors, providing a standardized severity indicator
  • Links to further information

The implementation relies on the RustSec website to publish per-crate advisory data in the standard OSV JSON format, which allows the crates.io frontend to fetch data directly.

Design Decisions

Several deliberate design choices shaped the feature:

Unmaintained advisories are excluded. RustSec tracks “unmaintained” crate advisories alongside vulnerability and unsoundness advisories. These have been a point of contention in the Rust community. On one hand, knowing that a dependency is no longer maintained is useful supply chain context. On the other hand, the risks of switching to an alternative may outweigh the risks of sticking with software that isn’t receiving updates — and when no alternatives exist, the advisory isn’t straightforwardly actionable. For the initial implementation, it made sense to focus on vulnerability and unsoundness advisories and leave the question of how (or whether) to display unmaintained advisories for later iteration.

Withdrawn advisories are hidden. If the RustSec database marks an advisory as withdrawn (typically because it was issued in error or the underlying issue was reassessed), the Security tab does not display it.

The tab is always present. Rather than hiding the Security tab when there are no advisories, it’s always visible. This avoids creating a situation where the absence of the tab is taken to mean “no vulnerabilities” — it simply means no advisories have been reported to RustSec for this crate.

No quality scoring. The tab does not attempt to summarize a crate’s security posture into a score or rating. Widely used, actively maintained crates are more likely to have advisories reported against them precisely because they get more scrutiny. A simplistic score would penalize the crates that are doing the most to address known issues.

Current Status and What’s Next

As of early 2026, approximately 700 crates have advisories displayed on their Security tab. The feature shipped as part of the crates.io development update in January 2026.

Work to display aggregate CVSS severity scores is underway; because the OSV format doesn’t represent this data directly, there has been some discussion on how best to implement this. (See PRs #12820 and #12825.)

Broader Context

This work is one piece of a broader effort to improve the security posture of the Rust ecosystem, funded by Alpha-Omega through the Rust Foundation. Other recent security improvements to crates.io include Trusted Publishing (which eliminates the need for long-lived API tokens), Trusted Publishing-only mode, and the blocking of risky GitHub Actions triggers from the publishing flow.

Together, these changes represent a shift toward making security visible and actionable at every stage of the Rust package lifecycle — from discovering a crate, to depending on it, to publishing new versions.

Acknowledgments

This work was funded by the OpenSSF Alpha-Omega project through the Rust Foundation. I’m grateful to Tobias Bieniek for his guidance on the codebase and to everyone who provided constructive feedback during the RFC process.

Author Bio

Dirkjan Ochtman is a professional Rust maintainer who works on open source infrastructure including rustls, Hickory DNS, and the RustSec project.