Implementing Account Lockout Policies
1. Understanding Account Lockout Purpose
| Goal | Threat Mitigated |
|---|---|
| Slow brute force | Password guessing |
| Detect credential stuffing | Reused passwords from breaches |
| Force human attention | Bot automation |
| Alert user | Notify of suspicious activity |
Warning: Pure account lockout creates DoS vector. Combine with IP throttling, CAPTCHA, and risk-based unlocks.
2. Setting Failed Login Threshold
| Account Type | Threshold | Window |
|---|---|---|
| Standard user | 5–10 attempts | 15 min |
| Admin / privileged | 3–5 attempts | 15 min |
| Service account | 3 attempts | 5 min |
| High-risk (banking) | 3 attempts | 1 hour |
3. Implementing Automatic Lockout
Example: Redis-backed counter
const MAX = 5, WINDOW = 900, LOCK = 1800;
async function recordFailure(userId) {
const key = `auth:fail:${userId}`;
const count = await redis.incr(key);
if (count === 1) await redis.expire(key, WINDOW);
if (count >= MAX) {
await redis.set(`auth:lock:${userId}`, "1", "EX", LOCK);
await notifier.lockoutEmail(userId);
}
}
async function isLocked(userId) {
return Boolean(await redis.get(`auth:lock:${userId}`));
}
4. Setting Lockout Duration
| Strategy | Pattern |
|---|---|
| Fixed | 15 or 30 minutes |
| Exponential backoff | 5, 15, 60, 240 min per re-trigger |
| Permanent | Requires admin / email unlock |
| Risk-based | Length tied to risk score |
5. Implementing Manual Account Unlock
| Mechanism | Auth Required |
|---|---|
| Admin console | Admin role + audit log |
| Self-service via email link | Email ownership |
| Self-service via MFA | Valid second factor |
| Support ticket | ID verification |
6. Using Email Notification for Lockout
Example: Lockout email payload
Subject: Your account was locked due to suspicious activity
Hi {name},
We locked your account after 5 failed login attempts from:
IP: 198.51.100.42 (United States)
Time: 2026-05-18 14:32 UTC
Device: Chrome 124 on macOS
If this was you, click here to unlock: https://app/unlock?t=XYZ
If not, change your password immediately.
7. Implementing Account Unlock Flow
Self-Service Unlock
- User receives unlock email with signed token
- Click link → verify token signature + expiry (1 hour)
- Optional: require MFA challenge
- Clear failure counter and lockout key
- Force password reset if lockout caused by suspected breach
- Audit log unlock event
8. Preventing Account Enumeration via Lockout
| Anti-pattern | Fix |
|---|---|
| "Account locked" response | Return same generic error as bad password |
| Different timing for locked vs unknown | Constant-time path |
| Only locking real accounts | Lockout signals "account exists" |
| Solution | Track failures by IP+email combo, not just username |
9. Implementing IP-Based Lockout
| Layer | Threshold |
|---|---|
| Per IP | 20 failures / 15 min |
| Per IP + endpoint | 10 failures / 15 min |
| Per ASN | 500 failures / 1 hr (anti-botnet) |
| Allowlist | Office IPs exempt |
| Blocklist | Known TOR exits, abuse DBs |
10. Resetting Failed Attempt Counter
| Trigger | Action |
|---|---|
| Successful login | Delete counter |
| Password reset | Delete counter + lockout |
| Manual unlock | Delete counter |
| Time window expiry | Auto-expire via TTL |