Are UUIDs Secure for Session Tokens?
- UUID v4 has 122 bits of randomness — technically sufficient entropy for session tokens.
- However, UUID v4 uses a predictable format (8-4-4-4-12) that leaks information to attackers.
- For session tokens and CSRF protection, use crypto.randomBytes(32) or equivalent — more bits, no format constraints.
- UUID is fine for non-security IDs (order IDs, record keys). Use purpose-built token generators for auth.
Table of Contents
UUID v4 is random — but "random" doesn't automatically mean "secure for authentication." Session tokens, CSRF tokens, and password reset links have specific security requirements that UUID v4 satisfies in some ways but falls short in others. This guide breaks down exactly what UUID v4 offers from a security perspective and where purpose-built token generators are the better choice.
UUID v4 Entropy: How Random Is It Really?
A UUID v4 has 128 bits total, but 6 bits are fixed (the version and variant fields). That leaves 122 bits of randomness.
122 bits of entropy means an attacker would need to try 2^122 ≈ 5.3 × 10^36 values to guess a UUID by brute force. For comparison:
- A 256-bit hash (SHA-256) token: 256 bits of entropy
- A 128-bit token from crypto.randomBytes(16): 128 bits
- UUID v4: 122 bits
- A weak 8-character alphanumeric token: ~47 bits — easily brute-forced
At 122 bits, the raw entropy is adequate. An attacker cannot feasibly guess a UUID v4 session token. The concern is not the number of bits — it's the source of those bits and what the format reveals.
The Real Issue: UUID Format Leaks Information
UUID v4 always looks like this: xxxxxxxx-xxxx-4xxx-[89ab]xxx-xxxxxxxxxxxx
The version nibble (4) and variant bits (8, 9, a, or b) are always fixed. An attacker who sees your session token format immediately knows:
- It's a UUID v4 (the
4in position 15) - The variant byte is constrained to 4 possible values
- The token is exactly 36 characters in the standard format
This doesn't make the token guessable, but it does reduce the search space slightly (122 bits instead of 128) and means attackers can validate guesses without checking your database — they can filter out any 36-char string that isn't valid UUID v4 format.
A crypto.randomBytes(32) token (256-bit hex string) has no structure to filter against.
CSPRNG: Does UUID Use a Cryptographically Secure Source?
UUID v4's security also depends on where the random bits come from.
- Browser
crypto.randomUUID()— uses the cryptographic engine (CSPRNG). Cryptographically secure. - Node.js
crypto.randomUUID()— usessecure random generator. Cryptographically secure. - Python
uuid.uuid4()— usesos.urandom(). Cryptographically secure. - Java
UUID.randomUUID()— usesSecureRandom. Cryptographically secure. - Math.random()-based UUID libraries — NOT cryptographically secure. Never use these for security tokens.
Platform-provided UUID v4 generators use CSPRNGs. Third-party npm packages using Math.random() do not — always check the source.
The Verdict: When to Use UUID vs Dedicated Token Generators
Use UUID v4 for:
- Database primary keys and foreign keys
- Correlation IDs, trace IDs, request IDs
- Public-facing record identifiers (order IDs, invoice IDs)
- Idempotency keys in APIs
Use a dedicated token generator for:
- Session tokens (stored in cookies)
- CSRF tokens
- Password reset links
- API keys and OAuth access tokens
- Email verification tokens
// Node.js — preferred for session and auth tokens
const crypto = require('crypto');
// 32 bytes = 256 bits, no fixed structure
const sessionToken = crypto.randomBytes(32).toString('hex');
// "a3f8c2b1d4e5..." (64 hex chars)
// Or URL-safe base64 (shorter)
const csrfToken = crypto.randomBytes(32).toString('base64url');
// "a3f8c2b1d4e5..." (43 chars)
Security Property Comparison
| Property | UUID v4 | crypto.randomBytes(32) |
|---|---|---|
| Entropy | 122 bits | 256 bits |
| CSPRNG (platform libs) | Yes | Yes |
| Predictable format | Yes (version/variant bits) | No |
| Guessable offline | No | No |
| Suitable for session tokens | Marginal | Yes |
| Suitable for record IDs | Yes | Overkill |
| Standard format (DB column) | Yes | No |
Use the free UUID generator above for record IDs, test data, and API testing — not for generating session tokens or CSRF tokens in production.
Generate UUID v4 for Test IDs and API Testing
The Cheetah UUID Generator produces RFC-compliant UUID v4 strings from a CSPRNG — use them for record IDs, test fixtures, and Postman collections (not session tokens).
Open Free UUID GeneratorFrequently Asked Questions
Can I use UUID as a password reset token?
Technically possible with platform-provided UUID v4 generators, but not best practice. Password reset tokens should use crypto.randomBytes(32) or equivalent — more entropy, no format constraints, and harder to validate offline.
Is crypto.randomUUID() more secure than uuid npm package?
Both use CSPRNGs on modern platforms. crypto.randomUUID() is native (no dependency), which is preferable. The uuid npm package is fine for non-security uses but introduces a dependency for something the platform provides natively.
Do session tokens need to be human-readable like UUIDs?
No. Session tokens are stored in HTTP cookies or Authorization headers — they're never typed by hand. Opaque hex or base64 strings are fine and slightly more secure than structured UUIDs.
What's wrong with using Math.random() for UUID generation?
Math.random() is not a CSPRNG — its output is predictable given enough observations. Any UUID library using Math.random() internally produces guessable UUIDs. Always verify your UUID library uses the platform's CSPRNG.

