In September 2006, a Debian developer deleted two lines of code from OpenSSL to quiet a memory-checking tool. The change collapsed the library's random number generator down to a single predictable input: the process ID, which on Linux only ranges from 0 to 32,768. For nearly two years, every SSH key, SSL certificate, and DKIM key generated on Debian and Ubuntu systems came from a pool of roughly 32,768 possible values per key type — not the astronomical keyspace cryptography depends on. When researchers disclosed CVE-2008-0166 on May 13, 2008, they published the entire set of vulnerable keys, and system administrators worldwide spent weeks revoking and regenerating credentials. This is the essence of CWE-340, Generation of Predictable Numbers or Identifiers: when a system that's supposed to produce unguessable values instead produces ones an attacker can compute, enumerate, or brute-force, every control built on top of that value collapses with it.
What is CWE-340, and why do "random" identifiers keep turning out to be guessable?
CWE-340 describes any case where a security-relevant number or identifier is generated in a way an attacker can predict, closely related to CWE-330 (Use of Insufficiently Random Values). It keeps recurring because "randomness" is easy to fake convincingly. A value can look random — a 6-character alphanumeric code, a 128-bit-looking string, a UUID — while actually being derived from a timestamp, a database auto-increment counter, a low-entropy seed, or a weak pseudo-random number generator (PRNG) like rand() or Math.random(), none of which are cryptographically secure. Developers reach for these functions because they're fast and built-in, not realizing that session tokens, password-reset links, API keys, and record identifiers all need output from a cryptographically secure random number generator (CSPRNG) such as /dev/urandom, crypto.randomBytes(), or SecureRandom. The gap between "looks random" and "is unpredictable" is exactly where CWE-340 lives, and it has produced some of the most consequential vulnerabilities of the last two decades.
How did sequential document IDs expose 885 million files at First American Financial?
They exposed the files because the URLs that served customer documents simply incremented a number, and the application never checked whether the requester was authorized to view it. In May 2019, security journalist Brian Krebs reported that First American Financial Corporation — a Fortune 500 title insurance company — had exposed 885 million sensitive records dating back to 2003, including bank account numbers, Social Security numbers, and wire transaction receipts. Each document was reachable by changing a single digit in a predictable, sequential document ID; no authentication token, session check, or randomization stood in the way. Anyone who received one legitimate link to a closing document could enumerate millions of other customers' files just by editing the number. In 2021, the New York Department of Financial Services fined the company $500,000 — its first enforcement action under the state's cybersecurity regulation — for exactly this failure to control access to predictably identified records.
Why did predictable booking codes let researchers pull up strangers' flight reservations?
Because many airline reservation systems generate Passenger Name Record (PNR) locators — the 6-character codes printed on boarding passes — sequentially or with far less entropy than their alphanumeric format suggests. In January 2019, CERT/CC published Vulnerability Note VU#366782 after researchers demonstrated that check-in systems across dozens of airlines would return a traveler's full itinerary given only a guessed or scraped PNR, with no rate limiting or additional identity verification. Even though a 6-character alphanumeric code has a theoretical keyspace in the billions, sequential or time-correlated generation meant attackers could narrow the search dramatically — turning what should have been an unguessable identifier into a small, walkable range. Combined with codes routinely printed on discarded boarding passes and luggage tags, the flaw let researchers view and, in some tested systems, modify other passengers' bookings.
Can a manipulated random number generator undermine an entire VPN?
Yes — Juniper Networks proved it in December 2015, when an internal code review found unauthorized code embedded in ScreenOS, the operating system running its NetScreen firewalls. The tampered code altered the constant used by the Dual_EC_DRBG random number generator, a generator already viewed with suspicion by cryptographers for a suspected NSA backdoor. Whoever held the corresponding secret value could passively predict the "random" numbers ScreenOS produced and use that predictability to decrypt VPN traffic on affected devices. Juniper assigned CVE-2015-7755 to a related authentication bypass and patched the RNG issue across ScreenOS 6.2.0r15–6.2.0r19 and 6.3.0r12–6.3.0r20, versions that had been in production since 2012 — meaning enterprise VPN traffic may have been quietly decryptable for roughly three years before discovery. It's the clearest large-scale demonstration that predictable number generation isn't just a web-app bug class; it can break the cryptographic backbone of network security itself.
Why do embedded devices generate weak keys even when the crypto algorithm is sound?
Because the algorithm was never the weak link — the entropy feeding it was. In their widely cited 2012 study "Mining Your Ps and Qs," researchers Nadia Heninger, Zakir Durumeric, Eric Wustrow, and J. Alex Halderman scanned the public internet's RSA and DSA keys and found that 0.75% of TLS hosts shared public keys with at least one other host, and they were able to compute the private keys for 0.50% of TLS hosts and 0.03% of SSH hosts. The root cause was headless and embedded devices — routers, firewalls, and appliances — generating keys immediately at first boot, before their systems had collected enough environmental entropy (mouse movement, disk timing, network jitter) to seed a CSPRNG properly. Two devices booted from an identical firmware image at nearly the same moment could produce the same "random" prime factors, letting attackers who noticed the collision derive one device's private key from another's public key. This is CWE-340 at the hardware layer: the code called a secure-looking function, but the input feeding it wasn't secure at all.
How do you catch predictable-identifier bugs before attackers do?
You catch them by treating "is this value cryptographically random?" as a specific, testable question at every point a security-relevant identifier is created — not by assuming a function name like generateToken() or uuid() guarantees it. That means auditing source code for insecure RNG calls (rand(), Math.random(), System.currentTimeMillis() used as a seed, time-based UUID v1 generation for anything security-sensitive), checking whether session tokens, password-reset codes, API keys, and CSRF tokens are pulled from a CSPRNG with adequate length, and confirming that record identifiers exposed in URLs or APIs are paired with real authorization checks rather than relying on the ID itself as a secret. It also means watching your dependency tree: a project can write flawless randomness-handling code and still inherit a vulnerable PRNG through a transitive library, an outdated crypto package, or a compromised build tool that swaps in a weakened generator — which is precisely the kind of manipulation that turned Juniper's ScreenOS into a surveillance backdoor.
How Safeguard Helps
Safeguard is built to catch exactly this class of vulnerability across your software supply chain, not just in the code you wrote last week. Static analysis rules flag CWE-340 and CWE-330 patterns automatically — insecure RNG calls, timestamp- or counter-derived tokens, and sequential identifiers used in authentication, session management, or password-reset flows — so the problem surfaces in code review, not in a breach report. Software composition analysis maps every cryptography and UUID-generation library in your dependency tree against known CVEs like CVE-2008-0166 and flags outdated or weakened PRNG implementations before they ship. Because Safeguard tracks build provenance and generates SBOMs across your pipeline, it can also detect when a build step, container base image, or third-party component has been tampered with in ways that degrade entropy sources — the same category of attack that compromised ScreenOS. Policy gates let teams block merges or releases that introduce insufficiently random token generation, and continuous monitoring extends that coverage into production, so a predictable identifier that slips through code review doesn't stay invisible until an attacker finds it first.