summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/caddyauth/hashes.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2020-10-31 10:51:05 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2020-10-31 10:51:05 -0600
commit937ec342010894f7a6239883b10f6a107ff82c9f (patch)
treee3dc861f6ac4e2675091b5c5b95d2ad3ffb96acb /modules/caddyhttp/caddyauth/hashes.go
parent966d5e6b42fc6da3da8bd39dd6ceceb8f1da3999 (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.go12
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)
)