← Back to Blog

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:

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:

  1. Observe a few generated passwords
  2. Reverse-engineer the PRNG state
  3. Predict all future password generations
  4. 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:

// ❌ DON'T DO THIS function generatePassword(length) { let password = ''; for (let i = 0; i < length; i++) { password += chars[Math.floor(Math.random() * chars.length)]; } return password; } // ✅ DO THIS INSTEAD function generateSecurePassword(length) { const array = new Uint32Array(length); crypto.getRandomValues(array); let password = ''; for (let i = 0; i < length; i++) { password += chars[array[i] % chars.length]; } return password; }

Why crypto.getRandomValues() is Secure

Best Practices for Password Generation

Secure Password Generation Checklist

  1. Use Web Crypto API: Always use crypto.getRandomValues() or crypto.randomUUID()
  2. Generate sufficient length: Minimum 12 characters, preferably 15+
  3. Use diverse character sets: Include uppercase, lowercase, numbers, and symbols
  4. Never reuse randomness: Generate fresh random values for each password
  5. Validate entropy: Ensure your generation method provides sufficient entropy

Implementation Example

Here's a complete, secure password generator implementation:

function generateSecurePassword(length = 16, options = {}) { const { includeUppercase = true, includeLowercase = true, includeNumbers = true, includeSymbols = true } = options; let charset = ''; if (includeLowercase) charset += 'abcdefghijklmnopqrstuvwxyz'; if (includeUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; if (includeNumbers) charset += '0123456789'; if (includeSymbols) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?'; const array = new Uint32Array(length); crypto.getRandomValues(array); let password = ''; for (let i = 0; i < length; i++) { password += charset[array[i] % charset.length]; } return password; }

🔐 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 Days

Affiliate link. SPG earns a commission at no extra cost to you.

Get the weekly password security brief

One breach, one fix, every week. No fluff.