Reject non-ASCII bytes in hash string to prevent panic (regression of #62)#103
Open
MuhammedHussein17 wants to merge 2 commits into
Open
Reject non-ASCII bytes in hash string to prevent panic (regression of #62)#103MuhammedHussein17 wants to merge 2 commits into
MuhammedHussein17 wants to merge 2 commits into
Conversation
…eats#62) A valid bcrypt hash is always 60 ASCII bytes. The parser rewrite in Keats#95 removed the is_char_boundary check that Keats#62's fix introduced. Rejecting non-ASCII up front in split_hash closes the entire class of byte-boundary panics across all five &str slices in the parser. Adds two regression tests: - verify_rejects_multibyte_utf8_in_hash: end-to-end via verify() - split_hash_rejects_non_ascii: direct parser-level test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Per private email discussion with @Keats — opening this as a regular bug fix.
Summary
bcrypt::verify/HashParts::from_strpanic instr::slice_error_failwhen given a 60-byte
&strcontaining a multi-byte UTF-8 character atcertain positions. This is a regression of the fix shipped in 2021 for
issue #62 (commit
0833509), which was lost during the parser rewritein PR #95 (
e9a8394, released as 0.19.0).Root cause
split_hashperforms five&strslicing operations on the input:&hash[1..3],&hash[4..6],&hash[7..],&salt_and_hash[..22], and&salt_and_hash[22..]. None of these are boundary-checked. Any inputwhere a multi-byte UTF-8 character spans one of those boundaries panics.
The previous parser had an
is_char_boundary(22)guard. After the rewrite,the existing regression test
does_no_error_on_char_boundary_splittingstill exists but is rejected earlier by the new
bytes[0] != b'$'checkand never actually reaches the buggy slices — which is why CI was green
on the regression.
Fix
Reject non-ASCII bytes in the hash string up front in
split_hash. Avalid bcrypt hash is always 60 ASCII bytes, so this closes the entire
class rather than guarding each slice individually.
Tests
Two new tests added (both fail on
master, pass with this change):verify_rejects_multibyte_utf8_in_hash— end-to-end viaverify()split_hash_rejects_non_ascii— direct parser-level assertionThe pre-existing
does_no_error_on_char_boundary_splittingtest iskept as-is.
Bonus: fuzz target was misnamed
fuzz/fuzz_targets/verify.rswas callingbcrypt::hashinstead ofbcrypt::verify, so the hash-string parser surface was never actuallyfuzzed. Fixed in the second commit. With the fix, future regressions
of this class should be caught by coverage-guided fuzzing.
Affects