Nadav Har'El created CASSANDRA-21744:
----------------------------------------
Summary: CREATE ROLE ... WITH HASHED PASSWORD accepts a bcrypt
hash with missing or extra characters
Key: CASSANDRA-21744
URL: https://issues.apache.org/jira/browse/CASSANDRA-21744
Project: Apache Cassandra
Issue Type: Bug
Reporter: Nadav Har'El
Since CASSANDRA-17334, {{RoleOptions.validate()}} validates a {{HASHED
PASSWORD}} by calling {{BCrypt.checkpw("dummy", hash)}}. It rejects a string
like {{'this_is_an_invalid_hash'}} with "Invalid hashed password value. Please
use jBcrypt.".
However, {{BCrypt.checkpw()}} parses only the setting at the beginning of the
hash: {{$2a$}}, the two-digit cost, {{$}} and the 22-character salt. It ignores
the rest. When the rest is wrong, it returns false instead of throwing. So a
string which starts with a valid bcrypt setting is accepted even if it is
truncated, has an extra character, or has no hash part at all. No password can
ever match such a string, so the role can never log in.
For example, {{$2a$04$PoiUnv/9OZ5nYjlN087uIe5KLMV6yJfDkgKAAHO0pRVTEvB3UQU/i}}
is a valid bcrypt hash of the password "super_secret_thing". All of the
following statements succeed:
{code:sql}
-- one character missing:
CREATE ROLE r1 WITH LOGIN = true AND HASHED PASSWORD =
'$2a$04$PoiUnv/9OZ5nYjlN087uIe5KLMV6yJfDkgKAAHO0pRVTEvB3UQU/';
-- one extra character:
CREATE ROLE r2 WITH LOGIN = true AND HASHED PASSWORD =
'$2a$04$PoiUnv/9OZ5nYjlN087uIe5KLMV6yJfDkgKAAHO0pRVTEvB3UQU/ix';
-- only the setting and salt, no hash:
CREATE ROLE r3 WITH LOGIN = true AND HASHED PASSWORD =
'$2a$04$PoiUnv/9OZ5nYjlN087uIe';
{code}
Expected: they should be rejected with "Invalid hashed password value", just
like {{'this_is_an_invalid_hash'}}.
h3. Possible fix
After the setting, a bcrypt hash contains the encoding of the 23-byte bcrypt
output, which is always 31 characters. So every valid bcrypt hash has exactly
the same length, 60 characters: 7 for {{$2a$NN$}}, 22 for the salt and 31 for
the hash. The crypt(5) manual page documents this format as:
{noformat}
\$2[abxy]\$[0-9]{2}\$[./A-Za-z0-9]{53}
{noformat}
jBCrypt's {{hashpw()}} always produces a string of this format.
So in addition to calling {{checkpw()}}, {{RoleOptions.validate()}} could check
that the given hash has the same length as {{BCrypt.hashpw("dummy", hash)}},
which is 60 characters. Or it could match the hash against the regular
expression above.
Reproduced on Cassandra 5.0.9 and 6.0-alpha2.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]