Skip to content

Commit e19d29b

Browse files
ReneWerner87claude
andcommitted
refactor(basicauth): simplify dummy verifier logic and improve docs
- Remove redundant hasDummy flag (zero-value verifierStrength always loses to real values) - Simplify Authorizer closure by directly reassigning verify variable - Document fallbackDummySHA512 preimage value at declaration site - Replace obfuscated hex byte array with string literal in test - Document mixed-hash timing limitation on buildVerifiers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7963956 commit e19d29b

2 files changed

Lines changed: 13 additions & 13 deletions

File tree

middleware/basicauth/basicauth_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,7 @@ func Test_buildVerifiers(t *testing.T) {
602602
verifiers, dummyVerify, err := buildVerifiers(nil)
603603
require.NoError(t, err)
604604
require.Empty(t, verifiers)
605-
// "fiber-basicauth-dummy"
606-
fallbackInput := string([]byte{
607-
0x66, 0x69, 0x62, 0x65, 0x72, 0x2d, 0x62, 0x61, 0x73, 0x69, 0x63, 0x61,
608-
0x75, 0x74, 0x68, 0x2d, 0x64, 0x75, 0x6d, 0x6d, 0x79,
609-
})
605+
fallbackInput := "fiber-basicauth-dummy"
610606
require.True(t, dummyVerify(fallbackInput))
611607
require.False(t, dummyVerify("wrong"))
612608
})

middleware/basicauth/config.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919

2020
var ErrInvalidSHA256PasswordLength = errors.New("decode SHA256 password: invalid length")
2121

22+
// fallbackDummySHA512 is SHA-512("fiber-basicauth-dummy"), used as a
23+
// constant-time comparison target when no users are configured.
2224
var fallbackDummySHA512 = [sha512.Size]byte{
2325
0x85, 0xc7, 0xd4, 0xbc, 0xec, 0x5f, 0xdf, 0xef, 0xe0, 0x4d, 0xd4, 0x3e, 0xd3, 0xac, 0x45, 0x7c,
2426
0x5e, 0x48, 0x60, 0x74, 0x12, 0x8e, 0xf8, 0xc0, 0xde, 0x39, 0x89, 0xf9, 0x84, 0x0c, 0x50, 0x24,
@@ -151,11 +153,10 @@ func configDefault(config ...Config) Config {
151153
}
152154
cfg.Authorizer = func(user, pass string, _ fiber.Ctx) bool {
153155
verify, ok := verifiers[user]
154-
v := dummyVerify
155-
if ok {
156-
v = verify
156+
if !ok {
157+
verify = dummyVerify
157158
}
158-
res := v(pass)
159+
res := verify(pass)
159160
return ok && res
160161
}
161162
}
@@ -188,7 +189,12 @@ type verifierStrength struct {
188189

189190
// buildVerifiers parses each configured user hash, stores the verifier by user,
190191
// and selects the strongest configured verifier for the dummy verification path.
191-
// It returns an error if any configured hash cannot be parsed.
192+
// The dummy verifier is used for unknown-user requests to equalize timing.
193+
//
194+
// Note: in mixed-hash deployments (e.g. bcrypt + SHA-256), the dummy matches
195+
// the strongest configured hash. Users with weaker hashes may still be
196+
// distinguishable from unknown users by timing. This is an accepted trade-off
197+
// since running all verifier types per request would be prohibitively expensive.
192198
func buildVerifiers(users map[string]string) (userVerifiers, passwordVerifier, error) {
193199
verifiers := make(userVerifiers, len(users))
194200
dummyVerify := fallbackDummyVerify
@@ -199,7 +205,6 @@ func buildVerifiers(users map[string]string) (userVerifiers, passwordVerifier, e
199205
sort.Strings(keys)
200206

201207
var dummyStrength verifierStrength
202-
hasDummy := false
203208
for _, user := range keys {
204209
hashedPassword := users[user]
205210
verify, err := parseHashedPassword(hashedPassword)
@@ -209,10 +214,9 @@ func buildVerifiers(users map[string]string) (userVerifiers, passwordVerifier, e
209214
verifiers[user] = verify
210215

211216
strength := verifierStrengthForHash(hashedPassword)
212-
if !hasDummy || strength.betterThan(dummyStrength) {
217+
if strength.betterThan(dummyStrength) {
213218
dummyVerify = verify
214219
dummyStrength = strength
215-
hasDummy = true
216220
}
217221
}
218222

0 commit comments

Comments
 (0)