ASVS 5.0 V7.2.3 (Level 1) requires that when you use opaque reference tokens as session identifiers, each one is unique, produced by a cryptographically secure pseudo random number generator (CSPRNG), and carries at least 128 bits of entropy.
Why it matters
A guessable session id is a login for anyone who can guess it. General purpose generators such as Math.random or a seeded rand call are predictable from a handful of outputs. Timestamps, counters and user ids make guessing worse. With 128 random bits, brute force across the whole internet is not realistic.
How to implement it
Use the operating system CSPRNG through your language's security API, and take at least 16 random bytes. 32 bytes is a comfortable default.
import secrets
token = secrets.token_urlsafe(32) # 256 bits
import { randomBytes } from "node:crypto";
const token = randomBytes(32).toString("base64url");
byte[] b = new byte[32];
new java.security.SecureRandom().nextBytes(b);
String token = java.util.Base64.getUrlEncoder().withoutPadding().encodeToString(b);
Store only a hash of the token server side, so a database leak does not hand out live sessions, and enforce uniqueness with a unique index. Most frameworks generate good ids already, so prefer the built in session middleware and check its configuration instead of writing your own.
How to test it
- Collect a few thousand session ids and inspect them. They should show no visible pattern, no shared prefix beyond a fixed marker, and no relationship to time or user.
- Check length. 128 bits is 22 base64url characters at a minimum, or 32 hex characters.
- Read the code that creates ids. Any use of non cryptographic random functions is a finding.
- Run a statistical sample test in a security tool if you want extra assurance, but the code review matters more.
Common mistakes
- Base64 encoding a user id plus a timestamp and calling it random.
- Counting characters instead of bits. A 20 character decimal string is only about 66 bits.
- Using a UUID version that is not random. Only version 4 from a CSPRNG qualifies, and even then it carries 122 random bits, so prefer raw bytes.
- Reusing a token after login (see V7.2.4).
Quick check
Is a version 4 UUID enough?
It has 122 random bits, which falls just short of 128. Use 16 or more raw random bytes instead.