0

I have some code that accepts a password in string format, and hash it with SHA3-512 before passing it to flask_bcrypt for hashing. However, by some coincidence, I found a test case that produces a hash that contains '\x00' in the middle of the hash result, as seen below:

password_str = 'tes15!tes15!tes15!tes15!tes15!tes15!tes15!tes15!tes15!tes15!tes15!tes15!.'
password_bytes = password_str.encode('utf-8')
hashed = hashlib.sha3_512(password_bytes).digest()

The result of the hash is:

b'u~"\x98\xac\xc8E2eV\xbb\x8e#}\x92R\xdc\xa2\xab\xab\xcb\x8d.~\x9f\x82a\xbf\xec]k\xdb\xc55\x1d\xa4\x00\xe8\x03\x94\xb0\x91\x14\xf0\x9ec\x9a\x9ay\xfeP\xe3\x07J\x00\xb5\xbd\xba\xcb(\xf5\xdb\xab\x1a'

As we can see, there is an '\x00' found in the middle of the hash, but not at the end. flask_bcrypt detects this a ValueError exception:

if b"\x00" in password:
    raise ValueError("password may not contain NUL bytes")

I understand that '\x00' is a reserved character and possible attack vector due to hash-length extension attacks. However, I do not think that I have done anything outside the ordinary. Is there a best practice that sanitizes the hash prior to passing it to bcrypt or flask_bcrypt that I am missing, or is there another type of byte-encoding that should be used with passwords?

It would be weird to reject a normal password just because it's derived hash conflicts with the auth library used.. Any help or advice is greatly appreciated. Thank you!

Benji Tan
  • 635
  • 7
  • 22

1 Answers1

0

BCrypt was designed to hash user passwords, this is not the same as e.g. SHA which is meant to hash binary input like a file. A user entered password actually never contains a \0 character, after all it is the user who desides about his own password, not a hacker trying to exploit a security vulnerability.

In other words, you should pass in the password as string directly, and avoid the UTF-8 encoding which converts it to a binary value.

martinstoeckli
  • 23,430
  • 6
  • 56
  • 87