Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.
Why this matters
The value is a token, secret, password, OTP, nonce, API key, or reset/verification code. random is a pseudo-random number generator seeded from predictable state and is NOT cryptographically secure: its output can be predicted or reproduced by an attacker, defeating the secret entirely.
Use the secrets module or os.urandom instead: secrets.token_urlsafe(32), secrets.token_hex(16), secrets.choice(alphabet), or os.urandom(32). These draw from the operating system's CSPRNG.
import osimport randomimport secretsimport string# ok: auth.py.flow.insecure-random-token -- CSPRNG via secrets.token_urlsafedef make_session_token(): session_token = secrets.token_urlsafe(32) return session_token# ok: auth.py.flow.insecure-random-token -- CSPRNG via os.urandomdef make_api_key(): api_key = os.urandom(32).hex() return api_key# ok: auth.py.flow.insecure-random-token -- CSPRNG via secrets.choicedef make_password(): alphabet = string.ascii_letters + string.digits password = "".join(secrets.choice(alphabet) for _ in range(16)) return password# ok: auth.py.flow.insecure-random-token -- non-security use of random (jitter)def retry_delay(): delay = random.random() return delay# ok: auth.py.flow.insecure-random-token -- non-security use of random (sampling)def pick_color(): color = random.choice(["red", "green", "blue"]) return color
Suppressing this rule
If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.