NVD — CVE-2026-71851: Insufficient randomness in crypto-js and cryptanalytic implications

09.09.2026

NVD — CVE-2026-71851: Insufficient randomness in crypto-js and cryptanalytic implications

Material type:  scientific and technical analytical article for WordPress.  Subject:  CVE-2026-71851, CWE-331, CWE-334, CWE-338, entropy generation for BIP39 and cryptographic keys.

Annotation

This article analyzes CVE-2026-71851, a vulnerability in the random value generation of the JavaScript library  crypto-js. In versions prior to 4.0.0, the method  CryptoJS.lib.WordArray.random() used an insecure user-defined Multiply-With-Carry (MWC) generator, initialized with [  Math.random()unclear] rather than a cryptographically secure randomness source. Requests for 128 and 256 bits of random data effectively boiled down to approximately the enumeration  2^39 and  2^47 state spaces, respectively.

The cryptanalytic significance of the flaw lies not in the weakening of AES, SHA-256, BIP39, or secp256k1 as algorithms, but in the predictable procedure for generating their secret input. If a weak output is used as the entropy of a BIP39 mnemonic phrase, an attacker can enumerate valid internal states, reproduce candidate mnemonics, and verify derived public keys or addresses. A fix is ​​announced in  crypto-js 4.0.0.

Keywords

crypto-js, CVE-2026-71851, NVD, CSPRNG, entropy, Multiply-With-Carry, Math.random(), BIP39, HD wallet, PBKDF2, secp256k1, CWE-338, cryptanalysis, brute-force attack.

1. NVD Recording Context

The US National Vulnerability Database (NVD) includes entry CVE-2026-71851, published on August 7, 2026, and modified on August 8, 2026; the entry’s source is listed as GitHub. At the time of publication of this page, NVD’s CVSS v4.0 score was unavailable. The attached CVSS v3.1 statement specifies the vector  CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N.

FieldMeaning and interpretation
IdentifierCVE-2026-71851
ComponentJavaScript library  crypto-js, function CryptoJS.lib.WordArray.random()
Affected rangeVersions before 4.0.0; the bug was introduced in 3.1.2-4 and was present in almost all 3.x releases.
Root causeCustom MWC generator seeded with value  Math.random(), instead of CSPRNG
The stated fixcrypto-js 4.0.0
Related CWECWE-331 (insufficient entropy), CWE-334 (small random space), CWE-338 (cryptographically weak PRNG)

A historical example.  This class of errors has a long practical history: predictable pseudorandom generators have led to the compromise of session identifiers, password reset tokens, and key material. The principle is general: a mathematically sound cryptosystem becomes insecure when its secret is selected from a small or reproducible set.

2. CVSS v3.1 Analysis

The vector describes a remote attack without prior privileges and without user interaction, with low complexity. Confidentiality is rated as high, since successfully recovering the seed or mnemonic allows the attacker to obtain private keys; integrity and availability are specified as unaffected in the vector itself.

MetricsMeaningPractical meaning
AVN — NetworkCandidate verification can be performed remotely using a published address, public key, or transaction history; access to the victim’s device is not a prerequisite for cryptanalysis.
ACL — LowOnce a weak generator has been established, the main operation is a reproducible enumeration of states, not a search for a new cryptographic attack on the primitive.
PRN — NoneAn attacker does not need an account or rights in the application if they have an external artifact to test.
UIN — NoneThe user is not required to click on a link or run a specially prepared file at the time of the attack.
SU — UnchangedThe consequence is considered in the same security area as the vulnerable application/wallet.
CH — HighRevealing the seed material means revealing the derivative secrets.
I / AN / N — NoneThe vector emphasizes the extraction of a secret; the actual disposal of assets after the key is stolen is an applied consequence that may extend beyond the formal boundary of the component.

Methodological clarification.  CVSS does not measure the cost of a brute-force attack on a specific infrastructure or provide proof of exploitation for every application. The actual risk depends on whether the dependent system specifically used this function for secrets, what data is available to the attacker, and how the candidate verification is structured.

3. Technical nature of the defect

A pseudorandom generator can be convenient for simulations, interface effects, or testing, but cryptographic generation requires unpredictability for an adversary even with knowledge of the algorithm. Kerckhoffs’s principle allows for the design to be publicly available; the internal unpredictable material must remain secret.

In vulnerable versions, the method  WordArray.random() obtained seemingly random words via MWC logic. However, the underlying initialization source——  Math.random() is not a contractually cryptographically secure API, and the added deterministic generator does not create new entropy: it only expands the limited initial state into a longer sequence.

R = G(s),   s ← Math.random()

H_inf(R) ≤ H_inf(s)

Here  G , is the deterministic transformation,  s is the seed,  R and is the returned array. The inequality expresses a key fact: deterministic postprocessing does not increase the minimum entropy of the initial state. Therefore, the length of the requested buffer is not equal to the actual strength of its origin.

4. MWC and the entropy limit

Multiply-With-Carry belongs to the family of fast recurrent generators. In one typical form, the state is updated by multiplying a portion of the previous state and carrying it, and the output is constructed from the least significant bits. The specific implementation coefficients may vary, but the presence of a small, deterministically evolving state is cryptanalytically important.

t_i = a x_i + c_i
x_(i+1) = t_i mod b
c_(i+1) = floor(t_i / b)

If the initial state space has cardinality  N, an exhaustive search requires 100 checks in the worst case  N and 100 checks on average  N/2. In the CVE description, the effective spaces are estimated to be approximately the same  2^39 for a nominal 128-bit space and  2^47 for a nominal 256-bit space.

Nominal requestEfficient space for recordingLoss relative to the stated sizeCryptanalytic interpretation
128 bits~2^39~89 bitsThe length of the result gives the false impression of 128-bit strength; the practical problem is determined by state search.
256 bits~2^47~209 bitsDoubling the buffer length does not double the entropy if the output depends on a small seed.

A historical example.  In 2008, the Debian OpenSSL incident demonstrated a similar structural effect: a build flaw radically reduced the available key generation material. Keys could have a valid RSA/DSA format and length, but they were chosen from a dangerously small set; this allowed lists of weak keys to be compiled and verified against known public data.

5. Communication with CWE

CWEThe meaning in this caseWhy one category is not enough
CWE-331 – Insufficient EntropyActual unpredictability is significantly less than expected.It identifies a deficit in entropy, but does not necessarily explain what exactly limits the set of results.
CWE-334 – Small Space of Random ValuesThe results come from a space of approximately  2^39 or  2^47, not from a space of size  2^128 or  2^256.Emphasizes the possibility of exhaustive search, but does not characterize the source of weakness as a PRNG.
CWE-338 — Use of Cryptographically Weak PRNGA sensitive operation was performed using a generator that does not meet cryptographic requirements.Describes the incorrect choice of mechanism, but does not replace quantitative analysis of entropy and state space.

A practical example:  In a web application, the same error might appear less critical for a decorative random color and more critical for an access recovery token. In a wallet, the seed is the root of trust: it determines all subsequent keys, so CWE-331, CWE-334, and CWE-338 overlap and reinforce each other.

6. Chain to BIP39

BIP39 describes the transformation of entropy into a mnemonic and the subsequent derivation of a seed using PBKDF2-HMAC-SHA512. These operations do not “fix” the weak source: they are deterministic transformations of the already chosen entropy. Hashing a weak secret obscures its representation but does not increase the number of possible initial secrets.

CS = first_ENT/32_bits(SHA256(ENT))
MNEMONIC = Encode_11bit(ENT || CS)
seed = PBKDF2-HMAC-SHA512(MNEMONIC, "mnemonic" || passphrase, 2048, 64)

For 128-bit entropy, BIP39 adds a 4-bit checksum and encodes 132 bits into 12 words; for 256-bit entropy, it adds an 8-bit checksum and 24 words. The checksum checks for writing errors but does not provide independent entropy. Similarly, PBKDF2 increases the cost of a single check, but does not restore the lost security when the initial candidate space is small.

StagePurposeDoes entropy deficit persist?
WordArray.random()Generates the source bytes.Yes, this is where the primary weakness arises.
SHA-256 checksumAdds BIP39 control bits.Yes is a deterministic function of  ENT.
BIP39 encodingRepresents bits as dictionary words.Yes, it changes form, not the power of the set.
PBKDF2-HMAC-SHA512Gets a 512-bit seed.Yes, it makes verification more difficult, but it doesn’t create new randomness.
BIP32/secp256k1Generates HD keys and public addresses.Yes – derived keys inherit the weakness of root selection.

A historical example.  The well-known incidents with Android Bitcoin wallets in 2013 were related to insufficient randomness in ECDSA signatures. There, the damage occurred due to weak or repeated nonces  k; in this case, the mechanism is different—the initial entropy of the mnemonic can be weak. Both cases confirm a general cryptographic principle: the security of elliptic curve cryptography depends not only on the curve but also on the quality of the secret random variables.

7. Cryptanalysis Model

The attack doesn’t require discrete logarithm inversion on secp256k1. It transforms the problem into a search over the reduced state space of the generator. For each candidate, the attacker reproduces the vulnerable function, constructs a BIP39 mnemonic, obtains the seed and derivation keys, and then compares the results with known public features.

for s in S:
  ENT = VulnerablePRNG(s)
  m = BIP39_Encode(ENT)
  seed = PBKDF2(m, salt, 2048)
  K = Derive(seed, path)
  if PublicIdentifier(K) == target: report candidate

Here  S is a set of possible internal states, or seeds. The identifier being verified could be an address, an extended public key, a known script, or another legitimately accessible public artifact. If the user has used an additional high-entropy BIP39 passphrase, it becomes a second secret and changes the attack model; an empty, generic, or guessable passphrase adds almost no protection.

Ethical Boundary.  This framework is intended for auditing your own applications, responding to incidents, and assessing risks. It should not be applied to third-party addresses, seeds, credentials, or assets without the owner’s explicit permission.

8. Evaluation of labor intensity

If the speed of the full verification pipeline is  r candidates per second, then the estimated time for a full scan is  T_full = 2^h / r, and the expected time to find a uniformly distributed state is  T_avg = 2^(h-1) / r. For this CVE, the parameter  h is assumed to be approximately 39 or 47, according to the entry description.

T_full = 2^h / r
T_avg = 2^(h - 1) / r

It’s important to distinguish between the byte generation speed and the speed of validating a candidate. A realistic evaluation should include BIP39 encoding, PBKDF2 with 2048 iterations, BIP32 derivation, possible derivation paths, and comparison with observed data. GPU or CPU parallelism, batch processing, and the number of paths tested change the practical cost but do not eliminate the fundamental gap between  2^47 and  2^256.

9. Affected scenarios

ScenarioRiskWhat to check during an audit
Generating BIP39 mnemonics with a browser walletCritical when using a function as the sole source of entropy.Version  crypto-js, call path, wallet creation history, presence of an additional passphrase, available public addresses.
Symmetric encryption keyHigh: The key can be enumerated if the ciphertext format yields a correctness oracle.Key source, dependency version, message format, AEAD/MAC authentication.
Salt or IVDepends on the protocol: uniqueness and unpredictability are required in different ways.Requirements of a specific algorithm, reuse, ability of the adversary to predict values.
UI identifier, test sampleUsually low unless the value serves a protective function.Whether the value has migrated to a token, credential, nonce, key, or recovery mechanism.

A real-life example:  A developer might assume that a call with an argument  32 automatically produces a “256-bit secret” due to the size of the returned array. CVE demonstrates why buffer size and actual entropy are different properties: security is determined by the unpredictable state, not the number of bytes printed.

10. Secure implementation

To generate keys, seeds, nonces, access tokens, and other cryptographically significant values, use the Web Crypto API in the browser  crypto.getRandomValues(); in Node.js, use the API of the module  node:crypto, such as  randomBytes(). These interfaces are designed to obtain randomness from the system cryptographic generator.

// Браузер: 256 бит энтропии из Web Crypto API
function secureEntropy(bytes = 32) {
  const out = new Uint8Array(bytes);
  crypto.getRandomValues(out);
  return out;
}

const entropy256 = secureEntropy(32);

In this example, 32 bytes is the length of the requested material; trust in its cryptographic validity is based on the Web Crypto API contract and the system CSPRNG, not a custom output extension  Math.random(). When generating a BIP39 phrase, the library should accept a byte array from such a source or use a verified internal CSPRNG.

// Node.js: серверная генерация случайных байтов
import { randomBytes } from 'node:crypto';

const entropy256 = randomBytes(32);

An example from engineering practice.  Migrating from  Math.random() a system-wide CSPRNG shouldn’t be done solely within a single mnemonic generator. It’s necessary to search for all security-sensitive calls: reset tokens, API keys, invitations, CSRF tokens, temporary passwords, salts, and nonces, assessing the requirements of each protocol separately.

11. Response and migration

  1. Inventory direct and transitive dependencies: lock files, SBOM, archived assemblies, CDN copies, and client bundles.
  2. Identify challenges  CryptoJS.lib.WordArray.random() and categorize the purpose of each result.
  3. Update  crypto-js to 4.0.0 or a newer compatible version; do not replace the problem with a home-made PRNG.
  4. For wallets and long-term keys generated from the affected path, treat the old secret as potentially compromised: generate a new seed on a trusted CSPRNG and transfer assets/identifiers according to the approved procedure.
  5. Preserve the minimum necessary evidence: package versions, build hashes, generation times, derivation paths, and public identifiers; do not place seeds and private keys in tickets, logs, or repositories.
  6. Add tests to prevent use  Math.random() for security-sensitive data and configure SCA/dependency auditing.

Archive example.  When investigating an old web wallet, it’s not enough to check the current package version: a vulnerable bundle could only have been used in a previous version of the site, and the seeds generated then remain weak even after a frontend update. Therefore, the release timeline and build artifact archive have forensic value in their own right.

12. Limitations of the analysis

The presence of a vulnerable version does not prove that a particular wallet is vulnerable: it is necessary to confirm the actual data path from  WordArray.random() the secret, the code version at the time of generation, and the absence of an independent strong source of entropy. Furthermore, the additional BIP39 passphrase, if truly random and not revealed, creates a separate barrier to brute-force attacks.

The numbers  2^39 and  2^47 should be interpreted as the effective space estimates given in the CVE entry, not as a universal instantaneous attack speed. Performance depends on the implementation, platform, set of derivation paths, available verification oracle, and computational architecture.

13. Conclusion

CVE-2026-71851 demonstrates a fundamental thesis of applied cryptography: the cryptographic strength of an algorithm does not compensate for the weakness of the secret selection procedure. In vulnerable versions,  crypto-js a nominally long random array could originate from a significantly smaller internal state space, turning an impossible brute-force attack on a 128- or 256-bit secret into an ordering  2^39 or  2^47 candidate problem.

This is especially important for BIP39 wallets, as the seed is the root of the key hierarchy. A robust strategy consists of using system-wide CSPRNGs, timely updates to patched versions, and retrospective audits of the generation and rotation paths of potentially affected key material.

Sources

CVE-2026-71851: Insufficient randomness in crypto-js: https://nefty.ru/cve-2026-71851-insufficient-randomness-in-crypto-js/

  1. NIST National Vulnerability Database.  CVE-2026-71851 Detail . Description, CWE-331, CWE-334, CWE-338, publication dates, and external links. URL:  https://nvd.nist.gov/vuln/detail/CVE-2026-71851 .
  2. GitHub Security Advisory.  GHSA-rg76-677x-56q9 . Link provided in NVD entry. URL:  https://github.com/brix/crypto-js/security/advisories/GHSA-rg76-677x-56q9 .
  3. The crypto-js repository. The commit identified by NVD as being associated with the fix. URL:  https://github.com/brix/crypto-js/commit/b405ff597fb3ac76a7bdfbc72dca10ba1079b1d5 .
  4. BIP-0039: Mnemonic code for generating deterministic keys. URL:  https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki .
  5. NIST SP 800-90A Rev. 1.  Recommendation for Random Number Generation Using Deterministic Random Bit Generators .