Security EngineerJuniorpythonflaskpostgresql

Hash Passwords Instead of Storing Plaintext

A real security problem you debug end to end in a live cloud workspace, then show on your portfolio. No tutorial, no toy app - a broken system that behaves like production.

Level
Junior
Time
~20 min
Cost
Free

The scenario

A security audit found that the user registration system stores passwords in plain text in PostgreSQL. If an attacker gets database access -- through SQL injection, a backup leak, or a compromised admin -- every user's password is immediately readable.

The broken code you start with

app.py (passwords stored in plaintext)
password = data.get("password", "")
# stored as-is - a DB leak exposes every password
cur.execute(
    "INSERT INTO users (username, email, password) VALUES (%s, %s, %s)",
    (username, email, password),
)

What this teaches you

What you did: /register now hashes via generate_password_hash() (PBKDF2 + per-user salt under the hood). /login uses check_password_hash() which does constant-time comparison against the stored hash. Plaintext never touches the DB.

Why it matters: Database breaches happen. If your passwords are plaintext, the attacker has logins for every user immediately AND can try those passwords on every other site (because users reuse). Hashing makes the breach an inconvenience instead of a catastrophe.

In the real world: Modern advice: bcrypt or argon2id, not raw PBKDF2 or SHA. The work-factor matters - too low and modern GPUs brute-force the hash table; too high and your login latency suffers. Cost-tune for ~250ms per check.

What you'll practice

Why this impresses a hiring manager

On your portfolio, this becomes

Switched /register to generate_password_hash() before storing, /login to check_password_hash() for verification - DB no longer holds raw passwords

Keep going

Close a SQL Injection in a Search EndpointSecurity projectSecurity roadmapStep by step to hiredSecurity interview questionsSTAR answersAll Security projectsProjects hub

Build this project free

You're in a real cloud workspace in 30 seconds. Fix it, and it lands on your portfolio.

Start this project →