Databases get leaked all the time: a stolen backup, an exposed admin panel, a bad query. When that happens, what’s stored in the password column decides how bad the day is. People reuse passwords, so a leak of your app’s passwords is also a leak of their email, bank, and Instagram passwords.
How to check2 min
Open your users table and look at the password column.
| What you see | Verdict |
|---|---|
hunter2 | Verdict:Plaintext. Fix before launch. |
aHVudGVyMg== | Verdict:Base64. That’s not security; anyone can decode it in one second. Fix. |
2ab96390c7dbe3439de74d0c9b0b1767 | Verdict:MD5 or SHA. Too fast, so easy to crack. Fix. |
$2b$12$Kx9... or $argon2id$... | Verdict:bcrypt or Argon2. You’re good. |
| No password column at all | Verdict:Probably fine. Auth is handled by Supabase, Firebase, Clerk, Auth0 etc. They hash for you. |
How to fix
Hashing means turning the password into a scrambled string that can’t be turned back. At login you hash what the user typed and compare the two scrambles. You never need to know the real password.
Use a slow hashing method built for passwords: bcrypt or Argon2. Never write your own.
const bcrypt = require("bcrypt"); // On signupconst hash = await bcrypt.hash(password, 12);await db.users.insert({ email, password_hash: hash }); // On loginconst ok = await bcrypt.compare(typedPassword, user.password_hash);Find everywhere this app stores or checks user passwords. Replace it with bcrypt hashing (cost 12). Write a one-time migration script that hashes all existing passwords in the database. Make sure passwords are never logged or returned in any API response.