diff options
author | Matthew Holt <mholt@users.noreply.github.com> | 2020-10-31 10:51:05 -0600 |
---|---|---|
committer | Matthew Holt <mholt@users.noreply.github.com> | 2020-10-31 10:51:05 -0600 |
commit | 937ec342010894f7a6239883b10f6a107ff82c9f (patch) | |
tree | e3dc861f6ac4e2675091b5c5b95d2ad3ffb96acb /modules/caddyhttp/caddyauth/hashes.go | |
parent | 966d5e6b42fc6da3da8bd39dd6ceceb8f1da3999 (diff) |
caddyauth: Prevent user enumeration by timing
Always follow the code path of hashing and comparing a plaintext
password even if the account is not found by the given username; this
ensures that similar CPU cycles are spent for both valid and invalid
usernames.
Thanks to @tylerlm for helping and looking into this!
Diffstat (limited to 'modules/caddyhttp/caddyauth/hashes.go')
-rw-r--r-- | modules/caddyhttp/caddyauth/hashes.go | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/modules/caddyhttp/caddyauth/hashes.go b/modules/caddyhttp/caddyauth/hashes.go index 5a3173e..63bfe1b 100644 --- a/modules/caddyhttp/caddyauth/hashes.go +++ b/modules/caddyhttp/caddyauth/hashes.go @@ -50,6 +50,11 @@ func (BcryptHash) Compare(hashed, plaintext, _ []byte) (bool, error) { return true, nil } +// Hash hashes plaintext using a random salt. +func (BcryptHash) Hash(plaintext, _ []byte) ([]byte, error) { + return bcrypt.GenerateFromPassword(plaintext, 14) +} + // ScryptHash implements the scrypt KDF as a hash. type ScryptHash struct { // scrypt's N parameter. If unset or 0, a safe default is used. @@ -113,6 +118,11 @@ func (s ScryptHash) Compare(hashed, plaintext, salt []byte) (bool, error) { return false, nil } +// Hash hashes plaintext using the given salt. +func (s ScryptHash) Hash(plaintext, salt []byte) ([]byte, error) { + return scrypt.Key(plaintext, salt, s.N, s.R, s.P, s.KeyLength) +} + func hashesMatch(pwdHash1, pwdHash2 []byte) bool { return subtle.ConstantTimeCompare(pwdHash1, pwdHash2) == 1 } @@ -121,5 +131,7 @@ func hashesMatch(pwdHash1, pwdHash2 []byte) bool { var ( _ Comparer = (*BcryptHash)(nil) _ Comparer = (*ScryptHash)(nil) + _ Hasher = (*BcryptHash)(nil) + _ Hasher = (*ScryptHash)(nil) _ caddy.Provisioner = (*ScryptHash)(nil) ) |