Skip to content

Security Issues and Concerns

Amitosh Swain Mahapatra edited this page Jul 1, 2020 · 2 revisions

bcrypt wrap-around bug (medium severity)

Versions < 5.0.0 suffer from the bcrypt wrap-around bug. Passwords greater than 255 characters were silently being trimmed. This could cause a long password to be trimmed incorrectly. Normally bcrypt trims passwords after the 72nd byte.

Chances of this being actually exploited is low as it is relatively uncommon to have passwords this big.

We tried to fix it in 2.x.x series but the attempt was incomplete.

Remedy

Upgrade to v5.0.0. However, this will create incompatibilities with users who actually used passwords > 255.

Improper NUL handling (medium severity)

bcrypt is based on C code and uses C stdlib functions for some of the string handlings. C uses "\0" or the NUL character to signify the end of a string. However, strings in JS do not treat NUL as a special character. Strings with an embedded NUL are thus improperly trimmed in bcrypt.

Remedy

Upgrade to v5.0.0. However, this will create incompatibilities with users who actually used passwords with NUL (this is however rare, NUL is not valid UTF-8 and can't be entered on a web form).

Timing Attacks

Because it's come up multiple times in this project, and other bcrypt projects, it needs to be said. The bcrypt comparison function is not susceptible to timing attacks. From codahale/bcrypt-ruby#42:

One of the desired properties of a cryptographic hash function is preimage attack resistance, which means there is no shortcut for generating a message which, when hashed, produces a specific digest.

A great thread on this, in much more detail can be found @ codahale/bcrypt-ruby#43

If you're unfamiliar with timing attacks and want to learn more you can find a great writeup @ [A Lesson In Timing Attacks][timingatk]

However, timing attacks are real. And, the comparison function is not time safe. What that means is that it may exit the function early in the comparison process. This happens because of the above. We don't need to be careful that an attacker is going to learn anything, and our comparison function serves to provide a comparison of hashes, it is a utility to the overall purpose of the library. If you end up using it for something else we cannot guarantee the security of the comparator. Keep that in mind as you use the library.