Skip to content
Fencer Intel
medium 5.3

RUSTSEC-2026-0199 json

Panic in `bcrypt::verify` on non-ASCII hash input

published 4mo ago modified 4mo ago

cvss
5.3
version 3.1, OSV
cisa kev
Not listed
not in CISA's catalog
epss
—
no score, EPSS covers CVEs only
public exploits
0
none known

Summary

`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`.

Patch / fix

  • crates.io bcrypt 0.19.2

Is RUSTSEC-2026-0199 in your dependencies? Fencer shows which of your repositories are affected as soon as an advisory lands, and opens the fix as a pull request.

Check with Fencer

CVSS scores

assigned by version score vector
OSV 3.1 5.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Affected packages

ecosystem package affected fixed in
crates.io bcrypt
>=0.19.0, <0.19.2
0.19.2

References

Sources

Fencer Intel keeps one entry per vulnerability: the CVE id wins, then GHSA, and records that alias each other are merged, except that two CVEs always keep separate entries. The same data is available as JSON.