Passwords stored as MD5
A easy Java puzzle in the security mistakes family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 6. Play this one as a puzzle without the answer.
What is wrong
MD5 is fast and unsalted here, so a stolen table can be cracked with precomputed tables and GPUs in minutes. Password storage needs a slow, salted, adaptive hash.
The fix
How to avoid it next time
Use a purpose-built password hash (bcrypt, Argon2, scrypt) and never a general-purpose digest.
Want the background? Read Password hashing (BCrypt, Argon2, PBKDF2) in the Java concepts library.
About security mistakes
Predictable random numbers, secrets in source code, unvalidated file paths and weak hashes turn working features into vulnerabilities. They pass every functional test.
In code review: Search for java.util.Random in security contexts, literals that look like keys, paths built from user input, and MD5 or SHA-1 used for passwords.
More puzzles in this family
Frequently asked questions
What is the bug in "Passwords stored as MD5"?
MD5 is fast and unsalted here, so a stolen table can be cracked with precomputed tables and GPUs in minutes. Password storage needs a slow, salted, adaptive hash. The faulty line is line 6: MessageDigest md = MessageDigest.getInstance("MD5");
How do I fix it?
Replace it with: return new BCryptPasswordEncoder().encode(password); // or Argon2, scrypt, PBKDF2. Use a purpose-built password hash (bcrypt, Argon2, scrypt) and never a general-purpose digest.
How do I catch security mistakes in code review?
Search for java.util.Random in security contexts, literals that look like keys, paths built from user input, and MD5 or SHA-1 used for passwords.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.