Skip to content

Commit 53a2db8

Browse files
committed
Address PR feedback
1 parent 16d3768 commit 53a2db8

4 files changed

Lines changed: 26 additions & 28 deletions

File tree

controllers/accounts_test.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,6 @@ func (suite *AccountsTestSuite) TestRegistration() {
303303
suite.Require().NoError(err)
304304
suite.NotNil(account.LastEmailVerifiedAt) // Email should now be verified
305305

306-
// Check that account is now verified
307-
account, err = suite.ds.GetAccount(nil, email)
308-
suite.Require().NoError(err)
309-
suite.NotNil(account.LastEmailVerifiedAt) // Email should now be verified
310-
311306
// Check that the session created has the correct version (PasswordAuthSessionVersion)
312307
sessionID, _, err := suite.jwtService.ValidateAuthToken(*verificationResult.AuthToken)
313308
suite.Require().NoError(err)

services/verification.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func (vs *VerificationService) CompleteVerification(verification *datastore.Veri
133133
}
134134
}
135135

136-
if util.NormalizeVerificationCode(code) != verification.Code {
136+
if !util.VerificationCodeEquals(code, verification.Code) {
137137
return nil, util.ErrInvalidCode
138138
}
139139

util/util.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -312,19 +312,20 @@ func (k *KeyServiceClient) MakeRequest(method string, path string, body interfac
312312
return nil
313313
}
314314

315-
// NormalizeVerificationCode applies canonical cleanup rules to a verification
316-
// code to tolerate common user input mistakes before comparison or storage.
317-
func NormalizeVerificationCode(code string) string {
318-
code = strings.ToUpper(code)
319-
code = strings.ReplaceAll(code, " ", "")
320-
code = strings.ReplaceAll(code, "\t", "")
321-
code = strings.ReplaceAll(code, "\n", "")
322-
code = strings.ReplaceAll(code, "\r", "")
323-
code = strings.ReplaceAll(code, "-", "")
324-
code = strings.ReplaceAll(code, "1", "I")
325-
code = strings.ReplaceAll(code, "8", "B")
326-
code = strings.ReplaceAll(code, "0", "O")
327-
return code
315+
// VerificationCodeEquals reports whether the user-supplied code matches the
316+
// stored normalized code, using a constant-time comparison to prevent timing
317+
// attacks.
318+
func VerificationCodeEquals(userInput, expected string) bool {
319+
userInput = strings.ToUpper(userInput)
320+
userInput = strings.ReplaceAll(userInput, " ", "")
321+
userInput = strings.ReplaceAll(userInput, "\t", "")
322+
userInput = strings.ReplaceAll(userInput, "\n", "")
323+
userInput = strings.ReplaceAll(userInput, "\r", "")
324+
userInput = strings.ReplaceAll(userInput, "-", "")
325+
userInput = strings.ReplaceAll(userInput, "1", "I")
326+
userInput = strings.ReplaceAll(userInput, "8", "B")
327+
userInput = strings.ReplaceAll(userInput, "0", "O")
328+
return subtle.ConstantTimeCompare([]byte(userInput), []byte(expected)) == 1
328329
}
329330

330331
func GetRequestLocale(explicitLocale string, r *http.Request) string {

util/util_test.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,24 @@ func (suite *UtilTest) TestCanonicalizeEmail() {
6262
suite.Equal("\"test@Foo\"@example.com", result)
6363
}
6464

65-
func (suite *UtilTest) TestNormalizeVerificationCode() {
65+
func (suite *UtilTest) TestVerificationCodeEquals() {
6666
// Uppercase
67-
suite.Equal("ABCDEF", util.NormalizeVerificationCode("abcdef"))
67+
suite.True(util.VerificationCodeEquals("abcdef", "ABCDEF"))
6868
// Whitespace removal
69-
suite.Equal("ABCDEF", util.NormalizeVerificationCode("ABC DEF"))
70-
suite.Equal("ABCDEF", util.NormalizeVerificationCode("AB\tCD\nEF"))
69+
suite.True(util.VerificationCodeEquals("ABC DEF", "ABCDEF"))
70+
suite.True(util.VerificationCodeEquals("AB\tCD\nEF", "ABCDEF"))
7171
// Hyphen removal
72-
suite.Equal("ABCDEF", util.NormalizeVerificationCode("ABC-DEF"))
72+
suite.True(util.VerificationCodeEquals("ABC-DEF", "ABCDEF"))
7373
// 1 -> I
74-
suite.Equal("IABCDE", util.NormalizeVerificationCode("1ABCDE"))
74+
suite.True(util.VerificationCodeEquals("1ABCDE", "IABCDE"))
7575
// 8 -> B
76-
suite.Equal("BABCDE", util.NormalizeVerificationCode("8ABCDE"))
76+
suite.True(util.VerificationCodeEquals("8ABCDE", "BABCDE"))
7777
// 0 -> O
78-
suite.Equal("OABCDE", util.NormalizeVerificationCode("0ABCDE"))
78+
suite.True(util.VerificationCodeEquals("0ABCDE", "OABCDE"))
7979
// Combined
80-
suite.Equal("IOBBCD", util.NormalizeVerificationCode("1 0-8-8cd"))
80+
suite.True(util.VerificationCodeEquals("1 0-8-8cd", "IOBBCD"))
81+
// Mismatch
82+
suite.False(util.VerificationCodeEquals("ABCDEF", "XYZXYZ"))
8183
}
8284

8385
func TestUtil(t *testing.T) {

0 commit comments

Comments
 (0)