From 8b9be01b86dc821d12a5821177646b74894c4257 Mon Sep 17 00:00:00 2001 From: Tiernan Messmer Date: Tue, 28 Sep 2021 19:22:11 +1000 Subject: [PATCH 1/2] Add go.mod file --- go.mod | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4b6a9f5 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/goji/httpauth + +go 1.17 From 81d1e0280bfde8b12959e72d573d7391ba578037 Mon Sep 17 00:00:00 2001 From: Tiernan Messmer Date: Tue, 28 Sep 2021 19:22:16 +1000 Subject: [PATCH 2/2] Compare user and pass hashes simultaneously to avoid leaking if the username is correct but not the password via a timing side channel. --- basic_auth.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/basic_auth.go b/basic_auth.go index a14c27a..38ae943 100644 --- a/basic_auth.go +++ b/basic_auth.go @@ -102,9 +102,14 @@ func (b *basicAuth) simpleBasicAuthFunc(user, pass string, r *http.Request) bool requiredUser := sha256.Sum256([]byte(b.opts.User)) requiredPass := sha256.Sum256([]byte(b.opts.Password)) + // Combine user and pass hashes together into single byte + // array to ensure constant time comparison no matter the + // combination of user or pass matching. + givenUserPass := append(givenUser[:], givenPass[:]...) + requiredUserPass := append(requiredUser[:], requiredPass[:]...) + // Compare the supplied credentials to those set in our options - if subtle.ConstantTimeCompare(givenUser[:], requiredUser[:]) == 1 && - subtle.ConstantTimeCompare(givenPass[:], requiredPass[:]) == 1 { + if subtle.ConstantTimeCompare(givenUserPass[:], requiredUserPass[:]) == 1 { return true }