Browse Source

security: prevent same passcode from being reused

Reported by @cezar97.
pull/5238/merge
Unknwon 7 years ago
parent
commit
01ccc2cc96
No known key found for this signature in database
GPG Key ID: 7A02C406FAC875A2
  1. 1
      conf/locale/locale_en-US.ini
  2. 2
      gogs.go
  3. 5
      models/user.go
  4. 11
      models/user_cache.go
  5. 468
      pkg/bindata/bindata.go
  6. 15
      routes/user/auth.go
  7. 2
      templates/.VERSION

1
conf/locale/locale_en-US.ini

@ -351,6 +351,7 @@ two_factor_or_enter_secret = Or enter the secret:
two_factor_then_enter_passcode = Then enter passcode: two_factor_then_enter_passcode = Then enter passcode:
two_factor_verify = Verify two_factor_verify = Verify
two_factor_invalid_passcode = The passcode you entered is not valid, please try again! two_factor_invalid_passcode = The passcode you entered is not valid, please try again!
two_factor_reused_passcode = The passcode you entered has already been used, please try another one!
two_factor_enable_error = Enable Two-factor authentication failed: %v two_factor_enable_error = Enable Two-factor authentication failed: %v
two_factor_enable_success = Two-factor authentication has enabled for your account successfully! two_factor_enable_success = Two-factor authentication has enabled for your account successfully!
two_factor_recovery_codes_title = Two-factor Authentication Recovery Codes two_factor_recovery_codes_title = Two-factor Authentication Recovery Codes

2
gogs.go

@ -16,7 +16,7 @@ import (
"github.com/gogits/gogs/pkg/setting" "github.com/gogits/gogs/pkg/setting"
) )
const APP_VER = "0.11.48.0426" const APP_VER = "0.11.49.0521"
func init() { func init() {
setting.AppVer = APP_VER setting.AppVer = APP_VER

5
models/user.go

@ -120,6 +120,11 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) {
} }
} }
// IDStr returns string representation of user's ID.
func (u *User) IDStr() string {
return com.ToStr(u.ID)
}
func (u *User) APIFormat() *api.User { func (u *User) APIFormat() *api.User {
return &api.User{ return &api.User{
ID: u.ID, ID: u.ID,

11
models/user_cache.go

@ -0,0 +1,11 @@
// Copyright 2018 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
// TwoFactorCacheKey returns key used for cache two factor passcode.
// e.g. TwoFactor_1_012664
func (u *User) TwoFactorCacheKey(passcode string) string {
return "TwoFactor_" + u.IDStr() + "_" + passcode
}

468
pkg/bindata/bindata.go

File diff suppressed because one or more lines are too long

15
routes/user/auth.go

@ -209,7 +209,9 @@ func LoginTwoFactorPost(c *context.Context) {
c.ServerError("GetTwoFactorByUserID", err) c.ServerError("GetTwoFactorByUserID", err)
return return
} }
valid, err := t.ValidateTOTP(c.Query("passcode"))
passcode := c.Query("passcode")
valid, err := t.ValidateTOTP(passcode)
if err != nil { if err != nil {
c.ServerError("ValidateTOTP", err) c.ServerError("ValidateTOTP", err)
return return
@ -224,6 +226,17 @@ func LoginTwoFactorPost(c *context.Context) {
c.ServerError("GetUserByID", err) c.ServerError("GetUserByID", err)
return return
} }
// Prevent same passcode from being reused
if c.Cache.IsExist(u.TwoFactorCacheKey(passcode)) {
c.Flash.Error(c.Tr("settings.two_factor_reused_passcode"))
c.Redirect(setting.AppSubURL + "/user/login/two_factor")
return
}
if err = c.Cache.Put(u.TwoFactorCacheKey(passcode), 1, 60); err != nil {
log.Error(2, "Failed to put cache 'two factor passcode': %v", err)
}
afterLogin(c, u, c.Session.Get("twoFactorRemember").(bool)) afterLogin(c, u, c.Session.Get("twoFactorRemember").(bool))
} }

2
templates/.VERSION

@ -1 +1 @@
0.11.48.0426 0.11.49.0521
Loading…
Cancel
Save