jypi
  • Explore
ChatWays to LearnMind mapAbout

jypi

  • About Us
  • Our Mission
  • Team
  • Careers

Resources

  • Ways to Learn
  • Mind map
  • Blog
  • Help Center
  • Community Guidelines
  • Contributor Guide

Legal

  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Content Policy

Connect

  • Twitter
  • Discord
  • Instagram
  • Contact Us
jypi

© 2026 jypi. All rights reserved.

CS50 - Introduction to Computer Science
Chapters

1Computational Thinking and Foundations

2C Language Basics

3Arrays, Strings, and Algorithmic Basics

4Algorithm Efficiency and Recursion

5Memory, Pointers, and File I/O

6Core Data Structures in C

7Python Fundamentals

8Object-Oriented and Advanced Python

9Relational Databases and SQL

10Web Foundations: HTML, CSS, and JavaScript

11Servers and Flask Web Applications

12Cybersecurity and Privacy Essentials

Threat ModelingOWASP Top 10 OverviewPasswords, Hashing, and SaltingCryptography BasicsSymmetric vs Asymmetric KeysTLS and HTTPSInput Validation and SanitizationXSS and CSRFSQL Injection DefensesSecure Session ManagementPrinciple of Least PrivilegeSecrets ManagementLogging and Audit TrailsIncident Response BasicsSecurity Testing Tools

13Software Engineering Practices

14Version Control and Collaboration

15Capstone: Designing, Building, and Presenting

Courses/CS50 - Introduction to Computer Science/Cybersecurity and Privacy Essentials

Cybersecurity and Privacy Essentials

5078 views

Write safer code by understanding common threats and defensive techniques.

Content

3 of 15

Passwords, Hashing, and Salting

Passwords, Hashing, and Salting for Secure Web Apps
1421 views
beginner
cybersecurity
web-development
flask
humorous
gpt-5-mini
1421 views

Versions:

Passwords, Hashing, and Salting for Secure Web Apps

Watch & Learn

AI-discovered learning video

Sign in to watch the learning video for this topic.

Sign inSign up free

Start learning for free

Sign up to save progress, unlock study materials, and track your learning.

  • Bookmark content and pick up later
  • AI-generated study materials
  • Flashcards, timelines, and more
  • Progress tracking and certificates

Free to join · No credit card required

Passwords, Hashing, and Salting — Practical Secure Storage for Flask Apps

Imagine your app is a castle. Passwords are keys. You would not store keys in a sticky note taped to the drawbridge, right? Welcome to the part where we stop doing that.


Why this matters (building on Threat Modeling and OWASP)

You already learned Threat Modeling and the OWASP Top 10. One of the recurring villains there is Broken Authentication — account takeover, credential stuffing, leaked databases. Threat modeling tells you attackers want access, so the most important defense is how you store and check credentials. If your Flask server and database (from Servers and Flask Web Applications) are the place where users log in, this is exactly where hashing and salting earn their keep.


What the terms mean, quickly

  • Password: what a user types to prove identity.
  • Hashing: running the password through a one-way function to produce a fixed-size string (a digest). You cannot feasibly reverse it.
  • Salt: a random value mixed into the password before hashing so that identical passwords do not produce identical hashes.
  • Pepper: a server-side secret added to every password before hashing (stored separately from the database).

Micro explanation

Hashing is like turning a key into a fingerprint. Salting is like stamping each key with a unique sticker before fingerprinting it — two identical keys no longer look identical in your records.


Bad idea vs good idea (the TL;DR)

Bad: store raw passwords in the users table. Also bad: store unsalted MD5/SHA1 of passwords. Attackers love rainbow tables and fast hashes.

Good: use a slow, adaptive password hash function like bcrypt, Argon2, or PBKDF2 with a unique salt per password, and an appropriate cost factor. Use a pepper if you want defense-in-depth.


Why slow hashing matters

Attackers run billions of guesses per second on GPUs and ASICs. Fast hashes (MD5, SHA256) let them try far more guesses. Slow adaptative hashes purposely take time and memory, making cracking expensive.

  • bcrypt: CPU-bound, cost factor (rounds) increases time.
  • Argon2: winner of the password hashing competition; tunable memory and time cost — great for modern security.
  • PBKDF2: widely supported, can be used safely with many iterations.

How to do this in a Flask app (practical example)

Assume a simple users table with columns: id, email, password_hash.

Python example using werkzeug security (convenient) and bcrypt via flask-bcrypt. These examples avoid double quotes so you can paste directly.

Code: storing a new user

from werkzeug.security import generate_password_hash, check_password_hash

# When creating account
plain = 'user password input'
hash = generate_password_hash(plain, method='pbkdf2:sha256', salt_length=16)
# store hash in users.password_hash

# For verification
is_ok = check_password_hash(hash, 'user entered password')

Code: using bcrypt (recommended) with flask-bcrypt

from flask_bcrypt import Bcrypt
bcrypt = Bcrypt(app)

pw = 'user password input'
hash = bcrypt.generate_password_hash(pw)  # includes salt automatically
# store hash.decode('utf-8')

# Check
bcrypt.check_password_hash(stored_hash, 'login attempt')

Notes:

  • Both methods include a unique salt per hash. You do not need to store the salt separately when using these libraries; the salt is embedded in the hash string.
  • For Argon2, use argon2-cffi. API is similar and supports memory and time tuning.

Salts, peppers, and storage details

  • Use a unique salt per user/password. That prevents attackers from exploiting duplicate passwords across accounts.
  • Store the salt in the database alongside the hash if your library does not embed it. Most modern libs embed it.
  • Pepper is optional: store it outside the database (in environment vars or secret manager). If the DB leaks, the attacker still needs the pepper. But beware: if pepper is in app code on the same host an attacker can reach, it is less effective.

Migration and upgrades

When you improve your hashing algorithm or cost factor:

  1. Store the new hashes using the new algorithm on next login or password change.
  2. For existing users, mark old hashes by algorithm/version and rehash on successful login.
  3. Optionally force password resets for highly sensitive systems.

Common pitfalls and attacks to watch

  • Reusing fast hashes like MD5/SHA1: cheap to crack.
  • Using the same salt globally: defeats the purpose; unique per-password is required.
  • Storing pepper in the same DB: one compromise = everything exposed.
  • Timing attacks on password comparison: use constant-time comparisons (check_password_hash handles this).
  • Poor password policies: weak user passwords still get cracked.

Integrating with your threat model

From Threat Modeling: identify the attacker and the asset (user accounts). For credential theft, prioritize the following mitigations:

  • Use strong hashing + salts + pepper if possible.
  • Improve account protections: MFA, rate limiting, IP or behavior-based locking.
  • Monitor for leaked hashes and rotate credentials if needed.

This fits naturally into the OWASP Top 10 item about Broken Authentication: correct password storage is the most important backend control to prevent large-scale account compromise.


Quick checklist for secure password storage

  • Use bcrypt, Argon2, or PBKDF2 with a high cost.
  • Use a unique salt per password.
  • Keep salts and hashes in the user table; pepper in a separate secret store.
  • Verify with constant-time checks.
  • Rehash on login when cost or algorithm changes.
  • Add MFA and rate limiting for defense-in-depth.

Key takeaways

  • Never store plain passwords. Ever.
  • Prefer slow, adaptive hashing algorithms with unique salts.
  • Use the right libraries in Flask to avoid mistakes; they handle salt details for you.
  • Combine hashed storage with multi-factor protections and monitoring as part of your threat model.

This is the moment where the concept finally clicks: hashes protect passwords from being immediately useful to attackers, salts prevent bulk compromise, and slow hashing makes cracking prohibitively expensive.


Need a tiny homework nugget? In your Flask app from Servers and Flask Web Applications, implement user registration and login using bcrypt or Argon2, log failed attempts, and add a simple rate limiter. You will see how these pieces from Threat Modeling and OWASP fit together like a security sandwich.

Flashcards
Mind Map
Speed Challenge

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Ready to practice?

Sign up now to study with flashcards, practice questions, and more — and track your progress on this topic.

Study with flashcards, timelines, and more
Earn certificates for completed courses
Bookmark content for later reference
Track your progress across all topics