Skip to content

RUSTSEC-2026-0097: phantom rand 0.8.5 in lockfile via optional rand feature #792

Description

@JudeMurphy

Problem

rust_decimal 1.41 declares rand = "0.8" as an optional dep (behind the rand feature). As of RUSTSEC-2026-0097 / GHSA-cq8v-f236-94qc — "Rand is unsound with a custom logger using rand::rng()" (2026-04-09) — every rand 0.8.x version is flagged, and there is no patched 0.8.x (the fix landed in 0.9.3).

Because cargo's resolver records optional-dep edges in Cargo.lock even when the activating feature is not enabled, every downstream crate that uses rust_decimal with default-features = false, features = ["serde","std"] (or similar minimal feature sets) still ends up with rand 0.8.5 in its lockfile. Both cargo audit --deny warnings and GitHub Dependabot flag it. The dep is not actually compiled (verified below), but every downstream project still has to ship a local advisory ignore just to stay green.

Minimal repro

# Cargo.toml
[dependencies]
rust_decimal = { version = "1.41", default-features = false, features = ["serde", "std"] }
$ cargo audit
Crate:     rand
Version:   0.8.5
Title:     Rand is unsound with a custom logger using `rand::rng()`
Date:      2026-04-09
ID:        RUSTSEC-2026-0097
Dependency tree:
rand 0.8.5
└── rust_decimal 1.41.0
warning: 1 allowed warning found

Confirmed the dep is not actually pulled into the build:

  • cargo tree -e normal shows no rand under rust_decimal (only arrayvec, num-traits, serde)
  • verbose cargo build --release never invokes rustc --crate-name rand
  • nm libmycrate.so | grep -iE 'rand_core|rand_chacha|::rand::' returns zero symbols

So the actual attack surface is zero — it's purely a lockfile/scanner noise problem, but it's the same pattern as #766 (RUSTSEC-2026-0001 via rkyv) and is going to keep surfacing until the 0.8-line rand dep is retired.

Suggested fixes (any one works)

  1. Drop the rand (0.8) optional dep in the next minor release, keeping only rand-0_9 (added in feat: add rand-0_9 crate feature #702). Document the migration for users who were enabling the rand feature.
  2. Alias the rand feature to rand-0_9 — i.e. rand = ["rand-0_9"] and remove dep:rand. Keeps the feature name stable while moving users to the patched line.
  3. Bump the version constraint on the optional rand dep from "0.8" to ">=0.9.3". Breaking for anyone using rust_decimal's rand integration through the old API, but the rust_decimal-internal usage appears to be limited and migratable.

Happy to open a PR for any of these if one is preferred.

Why this matters

Dependabot's low-severity alerts from transitively-carried optional deps accumulate quickly across a large user base, and every downstream project is independently writing a .cargo/audit.toml ignore + a dismissal comment. A single upstream drop would clear the advisory for everyone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions