PT-2026-55717 · Crates.Io · Bcrypt

Published

2026-06-20

·

Updated

2026-06-20

CVSS v3.1

5.3

Medium

VectorAV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
bcrypt::verify(password, hash) and HashParts::from str(hash) panic in str::slice error fail when given a 60-byte &str containing a multi-byte UTF-8 character at certain byte positions.

Impact

Any Rust code that calls bcrypt::verify (or HashParts::from str) with an attacker-controlled hash string will panic. The bcrypt crate is #![forbid(unsafe code)], so this is limited to a denial-of-service and cannot lead to memory corruption.
Realistic attack contexts include:
  • Rust authentication services reading hashes from a database that was previously compromised via, e.g., SQL injection. The attacker can then crash the service on every login attempt against the tampered account.
  • CLI tools accepting hashes from stdin or command-line arguments.
  • Password managers or vault services loading hashes from untrusted configuration sources.

Root cause

split hash performed five &str slicing operations on the input hash: &hash[1..3], &hash[4..6], &hash[7..], &salt and hash[..22], and &salt and hash[22..]. None of these were char-boundary-checked. Any input where a multi-byte UTF-8 character spanned one of those byte positions caused a panic.
This is a regression of the fix originally shipped in 2021 for issue #62 (commit 0833509). The regression was introduced in the parser rewrite in PR #95 (commit e9a8394, released as 0.19.0).
The pre-existing regression test does no error on char boundary splitting was not removed, but was silently rendered ineffective by the new bytes[0] != b'$' guard, which rejected its input earlier and prevented it from reaching the buggy slices — leaving CI green through the regression.

Fix

split hash now rejects any hash string containing non-ASCII bytes up front. A valid bcrypt hash is always exactly 60 ASCII bytes, so this closes the entire class of byte-boundary panics rather than guarding each slice individually.
The fix was merged in PR #103 and released as bcrypt 0.19.2 on 2026-06-20.

Downstream impact

pyca/bcrypt (which depended on bcrypt 0.19.1) is not affected. Its Python-side wrapper performs its own byte-level salt parsing before invoking bcrypt::hash with salt, and never reaches the buggy code path in split hash or verify.

Fix

Found an issue in the description? Have something to add? Feel free to write us 👾

Related Identifiers

RUSTSEC-2026-0199

Affected Products

Bcrypt