Agent Wranglers

APS-11Required

Store passwords with a slow hash

Store passwords only as a slow, salted hash made for passwords, such as Argon2id or bcrypt.

How to do it

Use a maintained password hashing library. OWASP suggests Argon2id with 19 MiB of memory, 2 passes and 1 thread as a minimum. Use scrypt, or PBKDF2 with 600,000 rounds of HMAC-SHA-256 where FIPS rules apply. Use bcrypt with a cost of at least 10 only for older systems. Bcrypt reads only the first 72 bytes and ignores the rest, so two long passwords with the same start match. With bcrypt, refuse passwords over 72 bytes in UTF-8. Or pre-hash them with HMAC-SHA-256 and a secret key, and pass the base64 result to bcrypt. Never use a fast hash such as SHA-256 alone. Rehash old hashes when a user next logs in. A sign-in provider or library does this for you.

Examples

JavaScript example

// Node with the argon2 package: Argon2id is the default
import argon2 from 'argon2';
const hash = await argon2.hash(password);
const ok = await argon2.verify(hash, attempt);

Python example

# Python with argon2-cffi: Argon2id is the default
from argon2 import PasswordHasher
hasher = PasswordHasher()
hash_ = hasher.hash(password)
hasher.verify(hash_, attempt)  # raises VerifyMismatchError when wrong
if hasher.check_needs_rehash(hash_):
    hash_ = hasher.hash(attempt)

How to check

Look at a test user's row in the database. The password field starts with a marker such as $argon2id$, $scrypt$ or $2b$, never the password or a plain hex hash. An Argon2id hash shows m=19456,t=2,p=1 or higher. On a bcrypt system, a test sets a 100-byte password and then signs in with only its first 72 bytes, and the sign-in fails.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/authentication-and-sessions/password-storage">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.