Skip to content

Commit 67156d1

Browse files
authored
Truncate password before sending it to bcrypt (home-assistant#155950)
1 parent 45c0891 commit 67156d1

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

homeassistant/auth/providers/homeassistant.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,18 @@ def validate_login(self, username: str, password: str) -> None:
179179
user_hash = base64.b64decode(found["password"])
180180

181181
# bcrypt.checkpw is timing-safe
182-
if not bcrypt.checkpw(password.encode(), user_hash):
182+
# With bcrypt 5.0 passing a password longer than 72 bytes raises a ValueError.
183+
# Previously the password was silently truncated.
184+
# https://github.com/pyca/bcrypt/pull/1000
185+
if not bcrypt.checkpw(password.encode()[:72], user_hash):
183186
raise InvalidAuth
184187

185188
def hash_password(self, password: str, for_storage: bool = False) -> bytes:
186189
"""Encode a password."""
187-
hashed: bytes = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
190+
# With bcrypt 5.0 passing a password longer than 72 bytes raises a ValueError.
191+
# Previously the password was silently truncated.
192+
# https://github.com/pyca/bcrypt/pull/1000
193+
hashed: bytes = bcrypt.hashpw(password.encode()[:72], bcrypt.gensalt(rounds=12))
188194

189195
if for_storage:
190196
hashed = base64.b64encode(hashed)

tests/auth/providers/test_homeassistant.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,24 @@ async def test_changing_password(data: hass_auth.Data) -> None:
133133
data.validate_login("test-UsEr", "new-pass")
134134

135135

136+
async def test_password_truncated(data: hass_auth.Data) -> None:
137+
"""Test long passwords are truncated before they are send to bcrypt for hashing.
138+
139+
With bcrypt 5.0 passing a password longer than 72 bytes raises a ValueError.
140+
Previously the password was silently truncated.
141+
https://github.com/pyca/bcrypt/pull/1000
142+
"""
143+
pwd_truncated = "hWwjDpFiYtDTaaMbXdjzeuKAPI3G4Di2mC92" * 4 # 72 chars
144+
long_pwd = pwd_truncated * 2 # 144 chars
145+
data.add_auth("test-user", long_pwd)
146+
data.validate_login("test-user", long_pwd)
147+
148+
# As pwd are truncated, login will technically work with only the first 72 bytes.
149+
data.validate_login("test-user", pwd_truncated)
150+
with pytest.raises(hass_auth.InvalidAuth):
151+
data.validate_login("test-user", pwd_truncated[:71])
152+
153+
136154
async def test_login_flow_validates(data: hass_auth.Data, hass: HomeAssistant) -> None:
137155
"""Test login flow."""
138156
data.add_auth("test-user", "test-pass")

0 commit comments

Comments
 (0)