CVE-2026-71851: crypto-js: weak PRNG enables wallet key recovery
GHSA-rg76-677x-56q9 CRITICAL CISA: ATTENDCryptoJS versions before 4.0.0 shipped a custom Marsaglia-style PRNG seeded from Math.random() instead of a cryptographically secure source, so calls to CryptoJS.lib.WordArray.random() for 128 or 256 bits of entropy actually produced an effective search space of only about 2^39 to 2^47 possibilities — small enough to brute-force on commodity hardware. This matters because crypto-js has 2,899 downstream dependents and the flaw was confirmed exploited in the wild: Coinspect's Ill Bloom investigation traced coordinated wallet-draining waves to BIP39 recovery phrases generated through this function, with a documented lower bound of $5M stolen as of July 13, 2026. EPSS sits low at 0.32% (top 76th percentile) and there's no CISA KEV listing or public scanner template, which understates the real risk — this isn't a forward-looking probability problem, it's a retroactive one, since secrets already generated through the vulnerable path stay compromised even after upgrading. Patch to crypto-js 4.0.0+ immediately, but treat that as necessary and not sufficient: any long-term secret, key, or token ever generated via WordArray.random() in an affected window must be inventoried and rotated, because reinstalling the fix does not repair keys already derived from a predictable seed.
What is the risk?
CVSS 9.0 critical (AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H) is well justified: no privileges or user interaction are needed to exploit a value once it's known to have been generated by the vulnerable path, confidentiality/integrity/availability impacts are all high, and scope is changed because compromise of a generated secret extends beyond the vulnerable component into whatever system trusts that secret (wallets, sessions, API tokens). Attack complexity is rated high because the attacker must first determine that a specific secret was produced by the flawed generator and then enumerate the reduced search space — nontrivial but demonstrated as fully practical by Coinspect end-to-end, including derivation of working private keys from public blockchain data. EPSS (0.32%, ~76th percentile) understates real-world risk because EPSS models forward-looking exploitation probability for unpatched, network-reachable instances, not retroactive compromise of secrets already generated and persisted — which is the actual attack path here and is already confirmed active with real financial loss. No CISA KEV entry and no Nuclei template exist because this isn't a remotely scannable service vulnerability; it's a cryptographic weakness in a client-side/library function, so standard vulnerability-management tooling will systematically under-prioritize it.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| HF Datasets | npm | < 4.0.0 | 4.0.0 |
Do you use HF Datasets? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 step-
Upgrade crypto-js to 4.0.0 or later across all direct and transitive dependencies; where feasible, replace CryptoJS-based randomness entirely with the platform's native Web Crypto API (crypto.getRandomValues) or Node's crypto module rather than trusting the library's own fix. Audit your dependency tree (2,899 known dependents) to confirm whether any component actually calls WordArray.random() for security-sensitive values — merely depending on crypto-js < 4.0.0 is not itself exploitable, only actual use of that function for secrets is. Identify the time window and application versions during which the vulnerable path was live, and treat every long-term secret (wallet seed, session key, API token, encryption key) generated in that window as compromised — rotate it, do not simply reissue software. For any wallet-adjacent product, notify affected users explicitly that installing the update does not remediate previously generated recovery phrases; users must generate a brand-new phrase from a trustworthy source and migrate funds, never re-import the old one. Detection is limited since this isn't remotely scannable — rely on SCA/dependency scanning for crypto-js < 4.0.0 in your SBOM, and cross-check any exposed wallet addresses against Coinspect's public Ill Bloom checker at https://illbloom.org/ (addresses only — never enter recovery phrases or private keys into any third-party tool).
What does CISA's SSVC say?
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-71851?
CryptoJS versions before 4.0.0 shipped a custom Marsaglia-style PRNG seeded from Math.random() instead of a cryptographically secure source, so calls to CryptoJS.lib.WordArray.random() for 128 or 256 bits of entropy actually produced an effective search space of only about 2^39 to 2^47 possibilities — small enough to brute-force on commodity hardware. This matters because crypto-js has 2,899 downstream dependents and the flaw was confirmed exploited in the wild: Coinspect's Ill Bloom investigation traced coordinated wallet-draining waves to BIP39 recovery phrases generated through this function, with a documented lower bound of $5M stolen as of July 13, 2026. EPSS sits low at 0.32% (top 76th percentile) and there's no CISA KEV listing or public scanner template, which understates the real risk — this isn't a forward-looking probability problem, it's a retroactive one, since secrets already generated through the vulnerable path stay compromised even after upgrading. Patch to crypto-js 4.0.0+ immediately, but treat that as necessary and not sufficient: any long-term secret, key, or token ever generated via WordArray.random() in an affected window must be inventoried and rotated, because reinstalling the fix does not repair keys already derived from a predictable seed.
Is CVE-2026-71851 actively exploited?
No confirmed active exploitation of CVE-2026-71851 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-71851?
Upgrade crypto-js to 4.0.0 or later across all direct and transitive dependencies; where feasible, replace CryptoJS-based randomness entirely with the platform's native Web Crypto API (crypto.getRandomValues) or Node's crypto module rather than trusting the library's own fix. Audit your dependency tree (2,899 known dependents) to confirm whether any component actually calls WordArray.random() for security-sensitive values — merely depending on crypto-js < 4.0.0 is not itself exploitable, only actual use of that function for secrets is. Identify the time window and application versions during which the vulnerable path was live, and treat every long-term secret (wallet seed, session key, API token, encryption key) generated in that window as compromised — rotate it, do not simply reissue software. For any wallet-adjacent product, notify affected users explicitly that installing the update does not remediate previously generated recovery phrases; users must generate a brand-new phrase from a trustworthy source and migrate funds, never re-import the old one. Detection is limited since this isn't remotely scannable — rely on SCA/dependency scanning for crypto-js < 4.0.0 in your SBOM, and cross-check any exposed wallet addresses against Coinspect's public Ill Bloom checker at https://illbloom.org/ (addresses only — never enter recovery phrases or private keys into any third-party tool).
What systems are affected by CVE-2026-71851?
This vulnerability affects the following AI/ML architecture patterns: agent frameworks, AI agent wallet/payment integrations, authentication & session token generation, API key / credential issuance.
What is the CVSS score for CVE-2026-71851?
CVE-2026-71851 has a CVSS v3.1 base score of 9.0 (CRITICAL). The EPSS exploitation probability is 0.34%.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0010.001 AI Software Compliance Controls Affected
What are the technical details?
Original Advisory
### Summary `CryptoJS.lib.WordArray.random()` in affected versions is not a cryptographically secure random number generator. Nominal requests for 128 or 256 bits of entropy produce effective search spaces of approximately 2^39 and 2^47 possibilities — small enough to enumerate on commodity hardware. Coinspect's [Ill Bloom](https://www.coinspect.com/blog/ill-bloom-investigation/) investigation confirmed that downstream wallet applications used this function as the entropy source for BIP39 recovery phrases. **An application is affected only if it uses the vulnerable function to generate security-sensitive values.** Merely depending on `crypto-js < 4.0.0` is not sufficient to be exploitable. ### Details The affected implementation used a custom variation of George Marsaglia's Multiply-With-Carry PRNG, seeded from `Math.random()`. It was introduced in 3.1.2-4 (June 2014, commit brix/crypto-js@ff1f003) in response to issue \#7, and was present in every 3.x release except 3.2.0 and 3.2.1. That **change was reverted in 3.3.0** because it was considered a breaking change, so projects tracking the 3.x line could resolve to newer versions that still contained the weak generator. 4.0.0 replaced the generator with the platform's native cryptographic API. Applying PBKDF2, another KDF, or a cryptographic hash after the vulnerable generator does not restore missing entropy. ### Proof of concept Coinspect reproduced the attack end to end: 1. Reimplemented the affected `WordArray.random()` behavior. 2. Enumerated the feasible outputs of the underlying PRNG. 3. Converted candidate entropy values into valid BIP39 recovery phrases. 4. Derived private keys and addresses across the relevant derivation paths and networks. 5. Compared derived addresses against public blockchain data. 6. Recovered the private keys controlling funded addresses. ### Impact An attacker can enumerate the reduced output space and recover security-sensitive values generated through the affected function. Coinspect documented coordinated drain waves affecting addresses derived from vulnerable recovery phrases. As of July 13, 2026, the measured lower bound of stolen assets across the two events was approximately $5M. The consequences are persistent: * Updating an affected library or wallet does not strengthen a previously generated secret. * Importing the same recovery phrase into an updated software or hardware wallet does not remediate the issue. * Previously generated secrets may remain exploitable indefinitely. * Future deposits to an affected address may also be stolen. * Assets may remain exposed across networks or derivation paths that have not yet shown suspicious activity. ### Remediation **For projects:** 1. Upgrade `crypto-js` to version `4.0.0` or later. Where possible, replace CryptoJS randomness with the native Web Crypto API or Node.js `crypto` module. 2. Audit direct, downstream, and transitive dependencies for versions of `crypto-js` matching `< 4.0.0`. 3. Determine whether `CryptoJS.lib.WordArray.random()` was used to generate any security-sensitive values. 4. Identify the time periods and application versions during which the vulnerable generation path was present. 5. Treat all long-term secrets generated through an affected path as compromised and rotate them. 6. Notify affected users that installing an update is insufficient when a long-term secret was generated by the vulnerable code. **For wallet users:** create a new wallet with a newly generated recovery phrase from a trustworthy source and migrate assets to addresses derived from it. Do not import the existing recovery phrase into the new wallet. ### Public address checker Coinspect provides a public checker for addresses identified in the known Ill Bloom exposed-address datasets: [https://illbloom.org/](https://illbloom.org/) Only public blockchain addresses should be entered. Users must **never enter a recovery phrase**, seed phrase, mnemonic, private key, password, or wallet backup file. A match indicates that funds controlled by the same recovery phrase may be at immediate risk. A negative result only means that the submitted address was not found in the currently published datasets. ### References * Ill Bloom research site and public address checker: [https://illbloom.org/](https://illbloom.org/) * Coinspect investigation overview: [https://www.coinspect.com/blog/ill-bloom-investigation/](https://www.coinspect.com/blog/ill-bloom-investigation/) * CryptoJS issue \#7 — `randomBytes is not random enough`: [https://github.com/brix/crypto-js/issues/7](https://github.com/brix/crypto-js/issues/7) * Commit introducing the MWC-based implementation: [https://github.com/brix/crypto-js/commit/ff1f0032ff58aedfcc44eb6aa7b2c78207a98009](https://github.com/brix/crypto-js/commit/ff1f0032ff58aedfcc44eb6aa7b2c78207a98009) * Changes between CryptoJS `3.3.0` and `4.0.0`: [https://github.com/brix/crypto-js/compare/3.3.0...4.0.0](https://github.com/brix/crypto-js/compare/3.3.0...4.0.0) * Downstream `ferrumnet/bip39` fork: [https://github.com/ferrumnet/bip39](https://github.com/ferrumnet/bip39)
Exploitation Scenario
An attacker identifies that a target wallet application or AI-agent payment plugin depended on crypto-js < 4.0.0 and used WordArray.random() to generate BIP39 recovery phrases. The attacker reimplements the vulnerable Marsaglia-based PRNG offline and enumerates its full output space (~2^39–2^47 candidates, tractable on commodity hardware or cheap cloud compute), converting each candidate into a valid BIP39 mnemonic. For each candidate phrase, the attacker derives private keys and addresses across common derivation paths and networks, then compares the derived addresses against public blockchain data to find ones holding funds. Once a match is found, the attacker has the private key and can drain the address immediately — and because the underlying secret (not just the software) is broken, the same attack succeeds again on any future deposits to that same address, even after the victim updates their software, unless they migrate to an entirely new, properly generated recovery phrase.
Weaknesses (CWE)
CWE-331 Insufficient Entropy
Primary
CWE-334 Small Space of Random Values
Primary
CWE-338 Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)
Primary
CWE-331 Insufficient Entropy CWE-334 Small Space of Random Values CWE-338 Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG) CWE-331 — Insufficient Entropy: The product uses an algorithm or scheme that produces insufficient entropy, leaving patterns or clusters of values that are more likely to occur than others.
- [Implementation] Determine the necessary entropy to adequately provide for randomness and predictability. This can be achieved by increasing the number of bits of objects such as keys and seeds.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H References
Timeline
Related Vulnerabilities
CVE-2026-61667 9.9 DIRAC: SQLi chained into eval() gives RCE
Same package: datasets CVE-2026-50027 9.8 mcp-memory-service: auth bypass on document API
Same package: datasets CVE-2026-55178 7.5 GeoLens: IDOR leaks private datasets via AI metadata API
Same package: datasets CVE-2026-65010 6.6 Datasets: symlink following enables arbitrary file write
Same package: datasets CVE-2026-35492 6.5 kedro-datasets: path traversal enables arbitrary file write
Same package: datasets