From 888f2d9acc6046c7b0521a7da75abc749072433b Mon Sep 17 00:00:00 2001 From: MUHAMMED HUSSEIN Date: Fri, 3 Jul 2026 21:43:19 +0300 Subject: [PATCH] Add advisory for bcrypt panic regression (CVE candidate) Adds an advisory for the panic in bcrypt::verify on non-ASCII hash input, fixed in bcrypt 0.19.2 (Keats/rust-bcrypt PR #103). Affected: >= 0.19.0, < 0.19.2 Fixed: >= 0.19.2 --- crates/bcrypt/RUSTSEC-0000-0000.md | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 crates/bcrypt/RUSTSEC-0000-0000.md diff --git a/crates/bcrypt/RUSTSEC-0000-0000.md b/crates/bcrypt/RUSTSEC-0000-0000.md new file mode 100644 index 000000000..94571bf45 --- /dev/null +++ b/crates/bcrypt/RUSTSEC-0000-0000.md @@ -0,0 +1,74 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "bcrypt" +date = "2026-06-20" +url = "https://github.com/Keats/rust-bcrypt/pull/103" +references = [ + "https://github.com/Keats/rust-bcrypt/issues/62", + "https://github.com/Keats/rust-bcrypt/pull/95", + "https://github.com/Keats/rust-bcrypt/commit/f5f1ee2862c1198a85afe3c2f8cd80835162b7e9", +] +categories = ["denial-of-service"] +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L" +keywords = ["panic", "utf-8", "denial-of-service"] + +[versions] +patched = [">= 0.19.2"] +unaffected = ["< 0.19.0"] +``` + +# Panic in `bcrypt::verify` on non-ASCII hash input + +`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`.