This document describes the account lockout mechanism implemented to address the security vulnerability where accounts were not being locked after failed login attempts.
- Added
failed_login_attemptscolumn to track consecutive failed attempts - Added
last_failed_logincolumn to timestamp the last failed attempt - Added
locked_untilcolumn to store when the lockout expires
- Threshold: Account locks after 5 consecutive failed login attempts
- Lock Duration: 30 minutes by default (configurable)
- Automatic Reset: Failed attempts reset to 0 on successful login
- Expiration: Lockouts automatically expire after the duration
- Rate Limiting: Existing IP-based rate limiting maintained
- Account Locking: User-specific lockout mechanism
- Information Disclosure Prevention: Generic error messages for invalid credentials
- Automatic Cleanup: Expired lockouts are automatically reset
Enhanced with account lockout checking:
- Returns 423 (Locked) status if account is locked
- Includes
lockedUntiltimestamp in response - Tracks failed attempts and locks account after threshold
New endpoint to check account lockout status:
- Returns lockout status, failed attempts count, and lock expiration
- Useful for admin monitoring and user feedback
Applied to protected routes:
/api/auctions(POST) - Auction creation/api/auctions/:id/bid(POST) - Bid placement- Prevents locked users from performing actions
incrementFailedLoginAttempts(username)- Increments failed attempt counterlockAccount(username, duration)- Locks account for specified durationresetFailedLoginAttempts(username)- Resets failed attempts and unlocksisAccountLocked(username)- Checks if account is currently lockedresetExpiredLockouts()- Mass reset of expired lockouts
- Runs every 5 minutes
- Automatically resets expired lockouts
- Logs cleanup activity
- Works alongside existing rate limiting
- Maintains JWT token security
- Preserves existing validation middleware
const MAX_FAILED_ATTEMPTS = 5; // Lock after 5 failed attempts
const LOCK_DURATION_MINUTES = 30; // Lock for 30 minutesThese can be easily modified based on security requirements.
Run the test script to verify the implementation:
node test-account-lockout.jsThe test covers:
- User registration
- Failed login attempts tracking
- Account locking after threshold
- Lockout status checking
- Prevention of login while locked
- Account-specific lockout prevents targeted attacks
- IP-based rate limiting provides additional protection
- Failed attempts are logged for security monitoring
- Clear error messages inform users about lockout status
- Automatic unlock prevents permanent lockout
- Successful login resets failed attempt counter
- Security warnings logged when accounts are locked
- Lockout status endpoint enables admin monitoring
- Failed login attempts tracked for security analysis
server.js- Enhanced login endpoint, added middleware and endpointsdatabase.js- Updated schema and added lockout methods
test-account-lockout.js- Comprehensive test suiteACCOUNT_LOCKOUT_IMPLEMENTATION.md- This documentation
curl "http://localhost:3001/api/users/lockout-status?username=testuser"{
"username": "testuser",
"isLocked": true,
"failedLoginAttempts": 5,
"lastFailedLogin": "2024-03-28T12:00:00.000Z",
"lockedUntil": "2024-03-28T12:30:00.000Z"
}{
"username": "testuser",
"isLocked": false,
"failedLoginAttempts": 0,
"lastFailedLogin": null,
"lockedUntil": null
}- Configurable lockout thresholds per user role
- Email notifications for account lockouts
- Admin override capabilities
- Progressive lockout durations
- Geographic-based lockout policies
- Real-time lockout monitoring
- Failed login attempt analytics
- Security event logging
- Automated alerting for suspicious activity
This implementation provides a robust account lockout mechanism that significantly improves the security posture of the application while maintaining a good user experience.