Cap salt length before concatenating with plaintext for password updates (#17068)

## –> #16487
- Ensures length of salt is no larger than the key size. This ensures
the remaining space within the 72-byte limit for salt+hash is the
advertised 48 bytes, for the default salt size.
- Per [this
discussion](https://github.com/fleetdm/fleet/pull/16524#discussion_r1474675857),
we are assuming ASCII characters, and therefore 1byte:1char, for now –
unicode support may come later.
- Updated tests to follow.

## Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
Jacob Shandling 2024-02-28 11:16:02 -08:00 committed by GitHub
parent 4a97587edf
commit aadf82911a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 2 deletions

View file

@ -404,6 +404,7 @@ func saltAndHashPassword(keySize int, plaintext string, cost int) (hashed []byte
return nil, "", err
}
salt = salt[:keySize]
withSalt := []byte(fmt.Sprintf("%s%s", plaintext, salt))
hashed, err = bcrypt.GenerateFromPassword(withSalt, cost)
if err != nil {

View file

@ -164,11 +164,11 @@ func TestUserPasswordRequirements(t *testing.T) {
}
func TestSaltAndHashPassword(t *testing.T) {
passwordTests := []string{"foobar!!", "bazbing!!"}
goodTests := []string{"foobar!!", "bazbing!!", "foobarbaz!!!foobarbaz!!!foobarbaz!!!foobarbaz!!", "foobarbaz!!!foobarbaz!!!foobarbaz!!!foobarbaz!!!"}
keySize := 24
cost := 10
for _, pwd := range passwordTests {
for _, pwd := range goodTests {
hashed, salt, err := saltAndHashPassword(keySize, pwd, cost)
require.NoError(t, err)
@ -178,6 +178,14 @@ func TestSaltAndHashPassword(t *testing.T) {
err = bcrypt.CompareHashAndPassword(hashed, []byte(fmt.Sprint("invalidpassword", salt)))
require.Error(t, err)
// too long
badTests := []string{"foobarbaz!!!foobarbaz!!!foobarbaz!!!foobarbaz!!!!"}
for _, pwd := range badTests {
_, _, err := saltAndHashPassword(keySize, pwd, cost)
require.Error(t, err)
}
}
}