🔒️ 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

@@ -57,21 +57,21 @@ def recover_password(email: str, session: SessionDep) -> Message:
"""
user = crud.get_user_by_email(session=session, email=email)
if not user:
raise HTTPException(
status_code=404,
detail="The user with this email does not exist in the system.",
# Always return the same response to prevent email enumeration attacks
# Only send email if user actually exists
if user:
password_reset_token = generate_password_reset_token(email=email)
email_data = generate_reset_password_email(
email_to=user.email, email=email, token=password_reset_token
)
password_reset_token = generate_password_reset_token(email=email)
email_data = generate_reset_password_email(
email_to=user.email, email=email, token=password_reset_token
send_email(
email_to=user.email,
subject=email_data.subject,
html_content=email_data.html_content,
)
return Message(
message="If that email is registered, we sent a password recovery link"
)
send_email(
email_to=user.email,
subject=email_data.subject,
html_content=email_data.html_content,
)
return Message(message="Password recovery email sent")
@router.post("/reset-password/")
@@ -84,10 +84,8 @@ def reset_password(session: SessionDep, body: NewPassword) -> Message:
raise HTTPException(status_code=400, detail="Invalid token")
user = crud.get_user_by_email(session=session, email=email)
if not user:
raise HTTPException(
status_code=404,
detail="The user with this email does not exist in the system.",
)
# Don't reveal that the user doesn't exist - use same error as invalid token
raise HTTPException(status_code=400, detail="Invalid token")
elif not user.is_active:
raise HTTPException(status_code=400, detail="Inactive user")
user_in_update = UserUpdate(password=body.new_password)