RSTR-CRY-007 — Rust rand::thread_rng() for security

Summary

The rand crate's thread_rng() returns the per-thread default RNG. As of rand 0.7+ it is seeded from the OS CSPRNG, but the output stream is not specified to be cryptographically secure across crate versions, and historically the type behind thread_rng() has changed. For tokens, keys, nonces, and any other security-sensitive use, always use OsRng (or getrandom directly) so the guarantee is explicit and stable across rand releases.

Severity

Medium.

Languages

Rust.

What rastray flags

#![allow(unused)]
fn main() {
use rand::Rng;

let token: u64 = rand::thread_rng().gen();       // ← flagged
}

What rastray deliberately does not flag

  • rand::rngs::OsRng.
  • getrandom::getrandom(&mut buf).
  • ring::rand::SystemRandom::new().

How to fix it

#![allow(unused)]
fn main() {
use rand::rngs::OsRng;
use rand::RngCore;

let mut buf = [0u8; 32];
OsRng.fill_bytes(&mut buf);
}

Or with getrandom directly (zero deps):

#![allow(unused)]
fn main() {
let mut buf = [0u8; 32];
getrandom::getrandom(&mut buf).expect("entropy unavailable");
}

For UUIDs:

#![allow(unused)]
fn main() {
use uuid::Uuid;
let id = Uuid::new_v4();      // backed by getrandom
}

References