← All fixes

Fix it

Storing passwords with MD5 or SHA-1 — how to fix it

High severityCWE-916 (Use of Password Hash With Insufficient Computational Effort)

MD5, SHA-1, and plain SHA-256 are designed to be fast, which is exactly what you do not want for passwords. If your database leaks, an attacker can try billions of guesses per second against those hashes and recover most passwords quickly. Use a slow, salted password hash built for the job, like bcrypt or argon2.

Why it's a problem

Fast general-purpose hashes make offline cracking cheap, so a stolen users table with MD5 or SHA-1 hashes is effectively a list of plaintext passwords within hours. Purpose-built password hashes are deliberately slow and salted per user, which makes mass cracking impractical even after a breach.

The pattern

// far too fast, and unsalted
const hash = crypto.createHash("md5").update(password).digest("hex");

The fix

import bcrypt from "bcrypt";

// hash on signup (bcrypt salts automatically)
const hash = await bcrypt.hash(password, 12);

// verify on login
const ok = await bcrypt.compare(password, hash);

Why AI tools write this

createHash('md5') is a short, familiar line that produces a hash, so when the task is 'hash the password' it is a common completion, especially since MD5 examples are everywhere in training data. It runs and stores a hash; nothing signals that the hash is unsafe for passwords.

The quick fix

  • Hash passwords with bcrypt, scrypt, or argon2, never MD5, SHA-1, or plain SHA-256.
  • Let the library handle salting; do not roll your own.
  • On your next login for each user, re-hash with the strong algorithm and migrate.

Want to know if this pattern is already in a repo you shipped? Scan a public repo free, no account needed.

Scan a repo →
MD5 / SHA-1 Password Hashing — Why It's Unsafe and How to Fix It: Prbl