highLogins, sessions and access

Weak Hashing, Guessable Tokens or Unverified JWTs

A password hash, token or JWT check is done with a method that does not protect anything.

Why it matters

MD5 and SHA-1 are fast, which is exactly wrong for passwords: a leaked table can be cracked at billions of guesses per second. The random module is predictable by design. A JWT whose signature is not checked can be written by anyone. The standard library and PyJWT have the right tools, and swapping them in is a line each.

What it looks like

This is the shape of code that triggers the rule. AI tools produce it because it works, and nothing tells them it is unsafe.

MD5 password hash
hashed = hashlib.md5(password.encode()).hexdigest()

The smallest fix

minimal patch
# Passwords
from werkzeug.security import generate_password_hash, check_password_hash
hashed = generate_password_hash(password)          # or bcrypt / argon2
# Tokens
import secrets
token = secrets.token_urlsafe(32)
# JWTs
payload = jwt.decode(token, SECRET, algorithms=["HS256"], audience=AUD, issuer=ISS)

The better fix

If you have a few more minutes, this is the approach that holds up as the app grows.

safe alternative
# Use your framework's built-ins: Django's make_password /
# check_password, or passlib's CryptContext with bcrypt or argon2.
# For tokens that must be unguessable, secrets is the only module to use.

Let your AI tool fix it

When the scanner finds this in your project, it fills in the file and line for you. This is the prompt it gives you to paste into Claude Code, Cursor or whatever you use.

In [the file] at line [the line number]: [the flagged code]. If this hashes a password, switch to a slow salted hash (werkzeug, bcrypt or argon2). If it makes a token, use secrets.token_urlsafe(32). If it decodes a JWT, verify the signature with an explicit algorithms list and check audience and issuer.

How to check the fix worked

1. For JWTs, send a token with a tampered payload and confirm a 401.
2. For tokens, confirm two generated values are 32+ bytes and differ.
3. For passwords, confirm the stored hash starts with the algorithm name
   (pbkdf2, $2b$, $argon2).

Further reading