---
title: Authentication Codes Must Expire Quickly
impact: MEDIUM
impactDescription: limits window for code interception attacks
tags: authentication, codes, expiry, otp, security
---

## Authentication Codes Must Expire Quickly

Long-lived codes give attackers more time to intercept and use them. Short expiry limits the attack window.

**Incorrect (codes last too long):**

```go
// Code valid for 24 hours
db.SaveToken(userID, token, time.Now().Add(24 * time.Hour))
```

**Correct (short expiry with proper handling):**

```go
const CodeExpiry = 5 * time.Minute

func GenerateAuthCode(userID string) (string, error) {
    code := generateOTP() // 6-digit CSPRNG
    
    // Store in Redis with TTL
    err := redisClient.Set(ctx, "otp:"+userID, code, CodeExpiry).Err()
    return code, err
}

func VerifyAuthCode(userID, inputCode string) (bool, error) {
    storedCode, err := redisClient.Get(ctx, "otp:"+userID).Result()
    if err == redis.Nil {
        return false, nil // Expired or not found
    }
    
    if storedCode == inputCode {
        redisClient.Del(ctx, "otp:"+userID) // Single use!
        return true, nil
    }
    
    return false, nil
}
```

**Recommended expiry times:**
- 2FA/OTP: 5-10 minutes
- Password reset: 15-60 minutes
- Email verification: 24 hours

**Tools:** Redis (TTL), Database (expiry column), Manual Review
