🔒️ Ensure authentication takes constant time, to avoid enumeration attacks (#2105)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Sebastián Ramírez
2026-01-22 07:50:00 -08:00
committed by GitHub
parent 7107f7e83a
commit 689d7105e1
3 changed files with 31 additions and 19 deletions

View File

@@ -37,9 +37,17 @@ def get_user_by_email(*, session: Session, email: str) -> User | None:
return session_user
# Dummy hash to use for timing attack prevention when user is not found
# This is an Argon2 hash of a random password, used to ensure constant-time comparison
DUMMY_HASH = "$argon2id$v=19$m=65536,t=3,p=4$MjQyZWE1MzBjYjJlZTI0Yw$YTU4NGM5ZTZmYjE2NzZlZjY0ZWY3ZGRkY2U2OWFjNjk"
def authenticate(*, session: Session, email: str, password: str) -> User | None:
db_user = get_user_by_email(session=session, email=email)
if not db_user:
# Prevent timing attacks by running password verification even when user doesn't exist
# This ensures the response time is similar whether or not the email exists
verify_password(password, DUMMY_HASH)
return None
verified, updated_password_hash = verify_password(password, db_user.hashed_password)
if not verified: