fix(mfa): key TOTP replay guard on time step, not the code
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/base32"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -289,16 +290,19 @@ func ClearMFA(instanceID, userID string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// burnTOTPCode makes a code single-use for 90 seconds - longer than the +-1
|
||||
// step window it could still validate in. Redis is already required for
|
||||
// sessions.
|
||||
// burnTOTPCode makes a step single-use for 90 seconds - longer than the +-1
|
||||
// step window it could still validate in. Keyed on the time step the code
|
||||
// was accepted against, never on the code itself: a raw code sitting in a
|
||||
// Redis key name would be a currently-valid credential readable by anything
|
||||
// that can list keys. Redis is already required for sessions.
|
||||
func burnTOTPCode(userID, code string) error {
|
||||
if RedisClient == nil {
|
||||
return nil
|
||||
}
|
||||
ctx, cancel := mfaCtx()
|
||||
defer cancel()
|
||||
key := "km:totp:" + userID + ":" + code
|
||||
step := time.Now().Unix() / 30
|
||||
key := "km:totp:" + userID + ":" + strconv.FormatInt(step, 10)
|
||||
ok, err := RedisClient.SetNX(ctx, key, 1, 90*time.Second).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user