Why Math.random() is Dangerous for Passwords (and What We Use Instead)
Last updated: November 20, 2025
If you've ever written JavaScript code to generate passwords, you might have used Math.random(). It seems random enough, right? Wrong. Using Math.random() for password generation is a critical security vulnerability that can expose your users to predictable password attacks.
⚡ TL;DR
Math.random()is not cryptographically secure - it's predictable- Attackers can predict future values if they know previous outputs
- Use
crypto.getRandomValues()or the Web Crypto API instead - Never use pseudo-random number generators for security-sensitive operations
The Problem with Math.random()
Math.random() is a pseudo-random number generator (PRNG), not a cryptographically secure random number generator (CSPRNG). This means:
- It's predictable: Given enough previous outputs, attackers can predict future values
- It has a limited state: The internal state can be reverse-engineered
- It's not designed for security: It's optimized for speed, not unpredictability
In 2015, researchers demonstrated that they could predict Math.random() outputs in Chrome by analyzing just a few samples. This vulnerability has been exploited in real-world attacks.
Real-World Impact
When passwords are generated using Math.random(), attackers can:
- Observe a few generated passwords
- Reverse-engineer the PRNG state
- Predict all future password generations
- Compromise accounts with predictable passwords
🛑 Security Risk
If your application uses Math.random() for password generation, session tokens, or any security-sensitive values, you're vulnerable to prediction attacks.
The Solution: Web Crypto API
Modern browsers provide the Web Crypto API for cryptographically secure random number generation:
Why crypto.getRandomValues() is Secure
- Cryptographically secure: Uses the operating system's CSPRNG
- Unpredictable: Even with unlimited previous outputs, future values cannot be predicted
- High entropy: Draws from multiple entropy sources (hardware, system events, etc.)
- Standardized: Part of the W3C Web Crypto API specification
Best Practices for Password Generation
Secure Password Generation Checklist
- Use Web Crypto API: Always use
crypto.getRandomValues()orcrypto.randomUUID() - Generate sufficient length: Minimum 12 characters, preferably 15+
- Use diverse character sets: Include uppercase, lowercase, numbers, and symbols
- Never reuse randomness: Generate fresh random values for each password
- Validate entropy: Ensure your generation method provides sufficient entropy
Implementation Example
Here's a complete, secure password generator implementation:
🔐 Ready to Generate Secure Passwords?
Our password generator uses the Web Crypto API to create cryptographically secure passwords. All generation happens in your browser - we never see or store your passwords.
Conclusion
Math.random() is fine for games, simulations, and non-security applications. But for password generation, session tokens, encryption keys, or any security-sensitive operations, you must use cryptographically secure random number generation.
The Web Crypto API provides the tools you need. Use crypto.getRandomValues() for secure randomness, and your users will be protected against predictable password attacks.
Remember: Security isn't about making things "random enough" - it's about using the right tools for the job.
Use a Password Manager That Has Never Been Breached
NordPass uses XChaCha20 encryption, costs $17.16/year, and includes dark web monitoring. Free 30-day trial, no credit card required.
Try NordPass Free for 30 DaysAffiliate link. SPG earns a commission at no extra cost to you.