Fix F-07: pre-compute real Argon2 dummy hash via sync.Once
- auth/auth.go: add DummyHash() which uses sync.Once to compute
HashPassword("dummy-password-for-timing-only", DefaultArgonParams())
on first call; subsequent calls return the cached PHC string;
add sync to imports
- auth/auth_test.go: TestDummyHashIsValidPHC verifies the hash
parses and verifies correctly; TestDummyHashIsCached verifies
sync.Once behaviour; TestDummyHashMatchesDefaultParams verifies
embedded m/t/p match DefaultArgonParams()
- server/server.go, grpcserver/auth.go, ui/ui.go: replace five
hardcoded PHC strings with auth.DummyHash() calls
- AUDIT.md: mark F-07 as fixed
Security: the previous hardcoded hash used a 6-byte salt and
6-byte output ("testsalt"/"testhash" in base64), which Argon2id
verifies faster than a real 16-byte-salt / 32-byte-output hash.
This timing gap was measurable and could aid user enumeration.
auth.DummyHash() uses identical parameters and full-length salt
and output, so dummy verification timing matches real timing
exactly, regardless of future parameter changes.
This commit is contained in:
@@ -27,6 +27,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcias/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcias/internal/config"
|
||||
"git.wntrmute.dev/kyle/mcias/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcias/internal/model"
|
||||
@@ -96,13 +97,11 @@ func (u *UIServer) consumeTOTPNonce(nonce string) (int64, bool) {
|
||||
return pl.accountID, true
|
||||
}
|
||||
|
||||
// dummyHash returns a hardcoded Argon2id PHC string used for constant-time
|
||||
// dummy password verification when the account is unknown or inactive.
|
||||
// Security: the dummy hash uses OWASP-recommended parameters (m=65536,t=3,p=4)
|
||||
// to match real verification timing. F-07 will replace this with a
|
||||
// sync.Once-computed real hash for exact parameter parity.
|
||||
// dummyHash returns the pre-computed Argon2id PHC hash for constant-time dummy
|
||||
// verification when an account is unknown or inactive (F-07).
|
||||
// Delegates to auth.DummyHash() which uses sync.Once for one-time computation.
|
||||
func (u *UIServer) dummyHash() string {
|
||||
return "$argon2id$v=19$m=65536,t=3,p=4$dGVzdHNhbHQ$dGVzdGhhc2g"
|
||||
return auth.DummyHash()
|
||||
}
|
||||
|
||||
// New constructs a UIServer, parses all templates, and returns it.
|
||||
|
||||
Reference in New Issue
Block a user