04/27 Fixed some issues 2

This commit is contained in:
2026-04-27 13:46:02 -04:00
parent 821cd929f1
commit 7d27a8ec49
4 changed files with 39 additions and 17 deletions
+13 -2
View File
@@ -69,9 +69,17 @@ class User(UserMixin, db.Model):
@staticmethod
def verify_set_password_token(token):
"""Return the User whose token matches, or None if invalid/expired."""
"""Return the User whose token matches, or None if invalid/expired.
The final token comparison uses hmac.compare_digest so that the
comparison runs in constant time regardless of how many characters
match, preventing timing-based token enumeration attacks.
"""
import hmac
if not token:
return None
# Primary lookup is via DB index — compare_digest is a defense-in-depth
# guard applied after the row is retrieved to harden the string comparison.
user = User.query.filter_by(set_password_token=token).first()
if user is None:
return None
@@ -79,7 +87,10 @@ class User(UserMixin, db.Model):
return None
if now_eastern() > user.set_password_token_expires:
return None
# Constant-time comparison — prevents timing oracle on the stored token
if not hmac.compare_digest(user.set_password_token, token):
return None
return user
def __repr__(self):
return f'<User {self.username}>'
return f'<User {self.username}>'