fix: Truncate Long Passwords (>72 bytes) (#6335)

This commit is contained in:
Michael Genson
2025-10-09 18:46:06 -05:00
committed by GitHub
parent 5620370ade
commit b7b191a5ee
2 changed files with 36 additions and 11 deletions

View File

@@ -21,13 +21,16 @@ class FakeHasher:
class BcryptHasher: class BcryptHasher:
def _get_password_bytes(self, password: str) -> bytes:
return password.encode("utf-8")[:72]
def hash(self, password: str) -> str: def hash(self, password: str) -> str:
password_bytes = password.encode("utf-8") password_bytes = self._get_password_bytes(password)
hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt()) hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt())
return hashed.decode("utf-8") return hashed.decode("utf-8")
def verify(self, password: str, hashed: str) -> bool: def verify(self, password: str, hashed: str) -> bool:
password_bytes = password.encode("utf-8") password_bytes = self._get_password_bytes(password)
hashed_bytes = hashed.encode("utf-8") hashed_bytes = hashed.encode("utf-8")
return bcrypt.checkpw(password_bytes, hashed_bytes) return bcrypt.checkpw(password_bytes, hashed_bytes)

View File

@@ -2,21 +2,43 @@ from pytest import MonkeyPatch
from mealie.core.config import get_app_settings from mealie.core.config import get_app_settings
from mealie.core.security.hasher import BcryptHasher, FakeHasher, get_hasher from mealie.core.security.hasher import BcryptHasher, FakeHasher, get_hasher
from tests.utils.factories import random_string
def clear_hasher_cache():
get_hasher.cache_clear()
get_app_settings.cache_clear()
def test_get_hasher(monkeypatch: MonkeyPatch): def test_get_hasher(monkeypatch: MonkeyPatch):
try:
hasher = get_hasher() hasher = get_hasher()
assert isinstance(hasher, FakeHasher) assert isinstance(hasher, FakeHasher)
monkeypatch.setenv("TESTING", "0") monkeypatch.setenv("TESTING", "0")
clear_hasher_cache()
get_hasher.cache_clear()
get_app_settings.cache_clear()
hasher = get_hasher() hasher = get_hasher()
assert isinstance(hasher, BcryptHasher)
finally:
clear_hasher_cache()
def test_hasher_long_password(monkeypatch: MonkeyPatch):
try:
monkeypatch.setenv("TESTING", "0")
clear_hasher_cache()
hasher = get_hasher()
assert isinstance(hasher, BcryptHasher) assert isinstance(hasher, BcryptHasher)
get_app_settings.cache_clear() # Create a very long password which bcrypt doesn't support
get_hasher.cache_clear() password = random_string(256)
assert len(password) > 72
# Make sure our hasher still works even though the password is too long
hashed_password = hasher.hash(password)
assert hashed_password
assert hasher.verify(password, hashed_password)
finally:
clear_hasher_cache()