Rust's safety guarantees are real but partial. RustSec advisory database RUSTSEC-2024-0421 (idna 0.4.0 punycode label handling), RUSTSEC-2023-0065 (tokio named_pipe use-after-free on Windows), and the 2024 std-library advisory CVE-2024-24576 around Command argument quoting on Windows (BatBadBut) show that "safe Rust" does not mean "no CVEs." The Rust Security Response Working Group published 118 advisories in 2023 and 142 in 2024 in the RustSec database. Of those, roughly 23 percent involved unsafe blocks, 19 percent involved Rust-specific logic bugs with no C analog, and the remainder were API-level issues such as incorrect validation or cryptographic misuse. This post reviews the shape of that data, what it implies about memory-safety marketing claims, and how teams should adjust their audit focus when adopting Rust 1.80+ in production.
What do Rust CVE numbers actually look like over time?
They grew roughly linearly with crate volume, not with ecosystem risk. RustSec advisory counts moved from 34 in 2020 to 142 in 2024, while crates.io total published crates grew from about 50,000 to over 160,000 in the same window. Normalized to crates-per-advisory, the density has stayed between 1,000 and 1,200, suggesting advisory rate tracks ecosystem growth rather than degradation. CVSS distribution skews lower than C/C++: Rust advisories in 2024 had a median CVSS v3.1 base score of 5.9 versus 7.2 for glibc-family CVEs in the same year, based on NVD data. Critical (9.0+) Rust advisories remain rare; MITRE records three in 2024, all in Windows-specific code paths such as CVE-2024-24576 and the openssl crate's RUSTSEC-2024-0357.
Where do memory-safety bugs still appear in Rust?
They cluster in unsafe blocks, FFI boundaries, and unsafe impl of Send/Sync. RustSec tags show 87 advisories across 2022-2024 categorized as memory-unsafety, of which 71 pointed at hand-written unsafe code in the affected crate, 12 at FFI wrappers (for example around libssh2-sys or openssl-sys), and four at incorrect Send/Sync impls creating data races. Classic examples include RUSTSEC-2021-0128 (rkyv out-of-bounds read), RUSTSEC-2023-0034 (h2 frame handling), and CVE-2024-27308 in mio affecting the Windows IOCP path. The Rust compiler's own CVE list is small: rustc 1.0 through 1.84 has fewer than ten CVEs, mostly around std::fs::remove_dir_all TOCTOU (CVE-2022-21658) and Windows path canonicalization. These are the boundaries where Rust's type system cannot enforce invariants and where auditors should focus effort.
How does Rust compare against C and Go for equivalent categories?
For memory-safety CVEs specifically, Rust reduces them by roughly an order of magnitude at equivalent code volume. Microsoft's 2019 analysis of Windows CVE data attributed about 70 percent of annual CVEs to memory-safety issues in C and C++ codebases. Google's 2022 Android data showed a drop from 76 percent memory-safety share in 2019 to 36 percent in 2022 as Rust adoption in Android 13 grew; no memory-safety CVE has been filed against Android Rust code as of the Android Security Bulletin of April 2024. Go has its own memory-safety story but adds GC-related and data-race bugs: the Go team issued 19 security releases in 2023 covering net/http and crypto/tls, several involving incorrect length handling that in Rust would typically trigger a bounds-check panic rather than an exploitable overflow. The comparison is not apples-to-apples, but direction is consistent.
What non-memory vulnerability classes dominate Rust advisories?
Denial-of-service via panics, algorithmic complexity, and logic errors in cryptographic crates. About 41 percent of 2024 RustSec entries are DoS-class: unbounded allocation in quick-xml (RUSTSEC-2024-0418), quadratic parsing in serde_yaml before 0.9.34, and panic-on-malformed input in image 0.24.9. Cryptographic misuse is the next cluster: RUSTSEC-2024-0336 (rustls handshake), RUSTSEC-2023-0053 (webpki denial of service via OID parsing), and incorrect IV handling in aes-gcm-siv prior to 0.11.1. Supply-chain events also show up: the shc crate removal in January 2024 and typosquats against serde_json surfaced as advisories rather than CVEs. These categories argue for continuing fuzz testing (cargo-fuzz, libFuzzer), differential testing, and property-based testing (proptest 1.5, quickcheck 1.0) even when writing safe Rust.
What verification tooling is worth deploying in 2025?
A layered stack: cargo-audit 0.20, cargo-deny 0.14, Miri with -Zmiri-strict-provenance, and Kani 0.54 for model-checking unsafe code. cargo-audit pulls from the RustSec database; cargo-deny adds license and source-registry policy. Miri catches undefined behavior at the Stacked Borrows or Tree Borrows level and has found bugs in smallvec, bytes, and crossbeam that did not surface under normal testing. Kani, which lowers Rust to CBMC, is useful for bounded proofs over unsafe blocks; AWS used it to verify parts of s2n-quic. Loom 0.7 is worth running on concurrent code paths, as it systematically explores thread interleavings. For supply-chain posture, cargo-vet 0.9 and cargo-crev provide human review trails, and cargo-sbom plus CycloneDX 1.6 output covers SBOM generation against NTIA minimum elements.
How Safeguard Helps
Safeguard ingests CycloneDX 1.6 and SPDX 2.3 SBOMs for Rust projects and correlates components against RustSec advisories and the NVD without relying on OSV alone, so you see overlapping identifiers for the same issue. Its dependency graph highlights transitive crates with unsafe blocks and FFI shims, making audit scope explicit. Policy gates can block merges when a direct or transitive dependency has an unpatched RustSec advisory above a CVSS threshold, and VEX documents (CSAF 2.0) let you mark non-exploitable findings so teams stay focused. Remediation plans suggest minimum-viable version bumps that respect semver and Cargo.lock determinism.