CWE-334, Small Space of Random Values, is what happens when the number of possible random values is smaller than the product needs. Even a perfect generator cannot help if the space of answers is tiny.
Anything that uses a code, ID or filename as a secret is affected.
How it happens
A short token drawn from a small alphabet has few possibilities. Five lowercase letters give about 12 million, which a script tries quickly. Observed examples:
- CVE-2002-0583: a product used 5 alphanumeric characters for filenames of expense claim reports stored under the web root.
- CVE-2002-0903: a small number of random numbers were used for a code to approve an action.
- CVE-2003-1230: a SYN cookie implementation used only 32-bit keys, making it easier to brute force the initial sequence number.
# Vulnerable: 4 digit code, 10,000 possibilities
code = f"{random.randint(0, 9999):04d}"
What an attacker gains
The attacker can guess the values easily, which can lead to unauthorized access by bypassing the protection those values provided.
How to find it
Calculate the size of the space for each secret: alphabet size to the power of length. Compare it with how fast an attacker can try guesses. Also check whether guessing is rate limited.
How to fix it
MITRE suggests using products or modules that conform to FIPS 140-2 to avoid obvious entropy problems. In practice, make the space large enough, with 128 bits a common target for secrets, draw from a secure generator, and add rate limits and lockouts on guess attempts.
code = secrets.token_urlsafe(16)
Quick check
Is a 6 digit code ever fine?
Only with strict limits on attempts and a short lifetime. The small space has to be offset elsewhere.