Skip to content

Commit 418c9f3

Browse files
Prevent bcrypt from raising a ValueError and log (#19078)
1 parent eac8626 commit 418c9f3

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

changelog.d/19078.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug introduced in 1.140.0 where an internal server error could be raised when hashing user passwords that are too long.

synapse/_scripts/hash_password.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,18 @@ def main() -> None:
7373

7474
pw = unicodedata.normalize("NFKC", password)
7575

76+
bytes_to_hash = pw.encode("utf8") + password_pepper.encode("utf8")
77+
if len(bytes_to_hash) > 72:
78+
# bcrypt only looks at the first 72 bytes
79+
print(
80+
f"Password is too long ({len(bytes_to_hash)} bytes); truncating to 72 bytes for bcrypt. "
81+
"This is expected behaviour and will not affect a user's ability to log in. 72 bytes is "
82+
"sufficient entropy for a password."
83+
)
84+
bytes_to_hash = bytes_to_hash[:72]
85+
7686
hashed = bcrypt.hashpw(
77-
pw.encode("utf8") + password_pepper.encode("utf8"),
87+
bytes_to_hash,
7888
bcrypt.gensalt(bcrypt_rounds),
7989
).decode("ascii")
8090

synapse/handlers/auth.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1683,8 +1683,22 @@ def _do_hash() -> str:
16831683
# Normalise the Unicode in the password
16841684
pw = unicodedata.normalize("NFKC", password)
16851685

1686+
bytes_to_hash = pw.encode(
1687+
"utf8"
1688+
) + self.hs.config.auth.password_pepper.encode("utf8")
1689+
if len(bytes_to_hash) > 72:
1690+
# bcrypt only looks at the first 72 bytes.
1691+
#
1692+
# Note: we explicitly DO NOT log the length of the user's password here.
1693+
logger.debug(
1694+
"Password is too long; truncating to 72 bytes for bcrypt. "
1695+
"This is expected behaviour and will not affect a user's ability to log in. 72 bytes is "
1696+
"sufficient entropy for a password."
1697+
)
1698+
bytes_to_hash = bytes_to_hash[:72]
1699+
16861700
return bcrypt.hashpw(
1687-
pw.encode("utf8") + self.hs.config.auth.password_pepper.encode("utf8"),
1701+
bytes_to_hash,
16881702
bcrypt.gensalt(self.bcrypt_rounds),
16891703
).decode("ascii")
16901704

0 commit comments

Comments
 (0)