Improper Randomness for Cryptographic hashlib
Functions
This rule detects the use of non-cryptographically secure randomness sources,
such as Python's random()
function, as inputs to cryptographic functions
like hashlib.scrypt()
. Using non-secure randomness sources can weaken the
cryptographic strength of functions that rely on unpredictability for security.
Cryptographic functions, including key generation, encryption, and hashing,
require a source of randomness that is unpredictable and secure against
attack. The standard random()
function in Python is designed for statistical
modeling and simulations, not for security purposes, as it generates
predictable sequences that can be reproduced if the seed value is known.
Using random()
for cryptographic purposes, such as generating salts or keys,
compromises security by making the output potentially predictable to attackers.
Ensure all cryptographic operations utilize a cryptographically secure source
of randomness. Python provides the secrets
module for generating secure
random numbers suitable for security-sensitive applications, including key
generation and creating salts for hashing functions.
Example
import hashlib
import random
password = b"my_secure_password"
salt = random.randbytes(16)
hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1)
Remediation
For security or cryptographic uses use a secure pseudo-random generator such
as os.urandom()
or secrets.token_bytes()
.
import hashlib
import os
password = b"my_secure_password"
salt = os.urandom(16)
hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1)
False Positives
In the case of a false positive the rule can be suppressed. Simply add a
trailing or preceding comment line with either the rule ID (PY035
) or
rule category name (improper_random
).
- Using rule ID
- Using category name
import hashlib
import random
password = b"my_secure_password"
salt = random.randbytes(16)
# suppress: PY035
hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1)
import hashlib
import random
password = b"my_secure_password"
salt = random.randbytes(16)
# suppress: improper_random
hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1)