584 lines
13 KiB
Markdown
584 lines
13 KiB
Markdown
|
|
# Authentication Security Implementation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
This document describes the comprehensive authentication security features implemented in the TV streaming application, including password policies, account lockout, password expiry, session management, and security audit logging.
|
||
|
|
|
||
|
|
## Features Implemented
|
||
|
|
|
||
|
|
### 1. Strong Password Policy
|
||
|
|
|
||
|
|
**Configuration** (`backend/utils/passwordPolicy.js`):
|
||
|
|
- Minimum length: 12 characters
|
||
|
|
- Required complexity:
|
||
|
|
- At least one uppercase letter
|
||
|
|
- At least one lowercase letter
|
||
|
|
- At least one number
|
||
|
|
- At least one special character
|
||
|
|
- Blocks 47 common passwords
|
||
|
|
- Prevents username/email in password
|
||
|
|
- Password strength calculation (0-100 score)
|
||
|
|
|
||
|
|
**Strength Levels**:
|
||
|
|
- 0-25: Very Weak (red)
|
||
|
|
- 26-50: Weak (orange)
|
||
|
|
- 51-75: Good (yellow)
|
||
|
|
- 76-90: Strong (light green)
|
||
|
|
- 91-100: Very Strong (green)
|
||
|
|
|
||
|
|
### 2. Account Lockout
|
||
|
|
|
||
|
|
**Default Settings**:
|
||
|
|
- Max failed attempts: 5
|
||
|
|
- Lockout duration: 30 minutes
|
||
|
|
- Automatic unlock after duration expires
|
||
|
|
|
||
|
|
**Behavior**:
|
||
|
|
- Failed login attempts are tracked per user
|
||
|
|
- After 5 failed attempts, account is locked for 30 minutes
|
||
|
|
- Lockout is logged in security audit
|
||
|
|
- Failed attempts counter resets on successful login
|
||
|
|
- Lockout status checked before password verification
|
||
|
|
|
||
|
|
### 3. Password Expiry
|
||
|
|
|
||
|
|
**Default Settings**:
|
||
|
|
- Password expiry: 90 days
|
||
|
|
- Warning period: 14 days before expiry
|
||
|
|
- Grace period: 3 days after expiry
|
||
|
|
- Can be disabled via configuration
|
||
|
|
|
||
|
|
**Behavior**:
|
||
|
|
- Password expiry date set on password change
|
||
|
|
- Warning shown in login response 14 days before expiry
|
||
|
|
- After expiry, user must change password to continue
|
||
|
|
- Grace period allows emergency access
|
||
|
|
|
||
|
|
### 4. Password History
|
||
|
|
|
||
|
|
**Configuration**:
|
||
|
|
- Tracks last 5 passwords
|
||
|
|
- Prevents password reuse
|
||
|
|
- Old passwords stored as bcrypt hashes
|
||
|
|
|
||
|
|
**Behavior**:
|
||
|
|
- On password change, current password saved to history
|
||
|
|
- New password checked against last 5 passwords
|
||
|
|
- Prevents users from cycling through passwords
|
||
|
|
|
||
|
|
### 5. Session Management
|
||
|
|
|
||
|
|
**Settings**:
|
||
|
|
- Max concurrent sessions: 5
|
||
|
|
- Session absolute timeout: 24 hours
|
||
|
|
- Session activity tracking
|
||
|
|
|
||
|
|
**Features**:
|
||
|
|
- All active sessions tracked in database
|
||
|
|
- Sessions include: IP address, user agent, timestamps
|
||
|
|
- Oldest session removed when limit reached
|
||
|
|
- Expired sessions cleaned up automatically every hour
|
||
|
|
- Session activity updated on each request
|
||
|
|
|
||
|
|
### 6. Security Audit Logging
|
||
|
|
|
||
|
|
**Events Tracked**:
|
||
|
|
- Authentication events (register, login, logout)
|
||
|
|
- Failed login attempts with IP and user agent
|
||
|
|
- Account lockouts
|
||
|
|
- Password changes
|
||
|
|
- 2FA events (enable, disable, verification)
|
||
|
|
- Privilege escalation
|
||
|
|
|
||
|
|
**Log Details**:
|
||
|
|
- User ID
|
||
|
|
- Event type and status (success/failed/pending)
|
||
|
|
- IP address
|
||
|
|
- User agent
|
||
|
|
- Timestamp
|
||
|
|
- Additional metadata
|
||
|
|
|
||
|
|
**Retention**:
|
||
|
|
- Logs retained for 90 days
|
||
|
|
- Automatic cleanup of old logs
|
||
|
|
|
||
|
|
## API Endpoints
|
||
|
|
|
||
|
|
### POST /api/auth/register
|
||
|
|
Register new user with password validation.
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"username": "john_doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"password": "SecureP@ssw0rd123"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Success):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"message": "Registration successful",
|
||
|
|
"token": "jwt_token",
|
||
|
|
"user": {
|
||
|
|
"id": 1,
|
||
|
|
"username": "john_doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"role": "user"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Weak Password):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Password does not meet requirements",
|
||
|
|
"details": [
|
||
|
|
"Password must be at least 12 characters long",
|
||
|
|
"Password must contain at least one special character"
|
||
|
|
],
|
||
|
|
"strength": {
|
||
|
|
"score": 45,
|
||
|
|
"level": "weak",
|
||
|
|
"feedback": "Add more characters and special symbols"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### POST /api/auth/login
|
||
|
|
Login with account lockout and password expiry checks.
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"username": "john_doe",
|
||
|
|
"password": "SecureP@ssw0rd123"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Success):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"message": "Login successful",
|
||
|
|
"token": "jwt_token",
|
||
|
|
"user": {
|
||
|
|
"id": 1,
|
||
|
|
"username": "john_doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"role": "user",
|
||
|
|
"must_change_password": false
|
||
|
|
},
|
||
|
|
"passwordWarning": "Your password will expire in 10 days. Please change it soon."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Account Locked):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Account locked. Try again in 25 minutes.",
|
||
|
|
"remainingMinutes": 25,
|
||
|
|
"locked": true
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Password Expired):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Your password has expired. Please change it to continue.",
|
||
|
|
"passwordExpired": true,
|
||
|
|
"requirePasswordChange": true
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### POST /api/auth/change-password
|
||
|
|
Change password with history check and validation.
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"currentPassword": "OldP@ssw0rd123",
|
||
|
|
"newPassword": "NewSecureP@ssw0rd456"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Headers**:
|
||
|
|
```
|
||
|
|
Authorization: Bearer jwt_token
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Success):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"message": "Password changed successfully"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response** (Password Reused):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Cannot reuse any of your last 5 passwords"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### POST /api/auth/check-password-strength
|
||
|
|
Check password strength without creating account.
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"password": "TestP@ssw0rd",
|
||
|
|
"username": "john_doe",
|
||
|
|
"email": "john@example.com"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"valid": true,
|
||
|
|
"errors": [],
|
||
|
|
"strength": {
|
||
|
|
"score": 78,
|
||
|
|
"level": "strong",
|
||
|
|
"feedback": "Good password strength"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### GET /api/auth/security-status
|
||
|
|
Get current user's security status.
|
||
|
|
|
||
|
|
**Headers**:
|
||
|
|
```
|
||
|
|
Authorization: Bearer jwt_token
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"twoFactorEnabled": true,
|
||
|
|
"passwordAge": 45,
|
||
|
|
"passwordExpiry": {
|
||
|
|
"expired": false,
|
||
|
|
"warning": true,
|
||
|
|
"daysRemaining": 10,
|
||
|
|
"message": "Your password will expire in 10 days. Please change it soon."
|
||
|
|
},
|
||
|
|
"lastLogin": {
|
||
|
|
"timestamp": "2024-01-15T10:30:00Z",
|
||
|
|
"ip": "192.168.1.100"
|
||
|
|
},
|
||
|
|
"activeSessions": 2,
|
||
|
|
"lastActivity": "2024-01-15T14:20:00Z",
|
||
|
|
"failedLoginAttempts": 0,
|
||
|
|
"recentEvents": [
|
||
|
|
{
|
||
|
|
"type": "login",
|
||
|
|
"status": "success",
|
||
|
|
"timestamp": "2024-01-15T10:30:00Z"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
### Environment Variables
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# JWT Configuration
|
||
|
|
JWT_SECRET=your_secret_key_here
|
||
|
|
JWT_EXPIRES_IN=7d
|
||
|
|
|
||
|
|
# Registration Control
|
||
|
|
DISABLE_SIGNUPS=true # Default: true, set to 'false' to enable public registration
|
||
|
|
```
|
||
|
|
|
||
|
|
### Password Policy Customization
|
||
|
|
|
||
|
|
Edit `backend/utils/passwordPolicy.js`:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const PASSWORD_POLICY = {
|
||
|
|
minLength: 12,
|
||
|
|
requireUppercase: true,
|
||
|
|
requireLowercase: true,
|
||
|
|
requireNumbers: true,
|
||
|
|
requireSpecialChars: true,
|
||
|
|
preventUsernameInPassword: true,
|
||
|
|
preventEmailInPassword: true
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### Account Lockout Customization
|
||
|
|
|
||
|
|
Edit `backend/utils/passwordPolicy.js`:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const ACCOUNT_LOCKOUT = {
|
||
|
|
enabled: true,
|
||
|
|
maxFailedAttempts: 5,
|
||
|
|
lockoutDuration: 30 * 60 * 1000 // 30 minutes in milliseconds
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### Password Expiry Customization
|
||
|
|
|
||
|
|
Edit `backend/utils/passwordPolicy.js`:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const PASSWORD_EXPIRY = {
|
||
|
|
enabled: true,
|
||
|
|
expiryDays: 90,
|
||
|
|
warningDays: 14,
|
||
|
|
gracePeriodDays: 3
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### Session Management Customization
|
||
|
|
|
||
|
|
Edit `backend/utils/passwordPolicy.js`:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const SESSION_POLICY = {
|
||
|
|
maxConcurrentSessions: 5,
|
||
|
|
absoluteTimeout: 24 * 60 * 60 * 1000, // 24 hours
|
||
|
|
inactivityTimeout: 30 * 60 * 1000 // 30 minutes
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## Database Schema
|
||
|
|
|
||
|
|
### New Tables
|
||
|
|
|
||
|
|
**password_history**:
|
||
|
|
```sql
|
||
|
|
CREATE TABLE password_history (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
user_id INTEGER NOT NULL,
|
||
|
|
password_hash TEXT NOT NULL,
|
||
|
|
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
**login_attempts**:
|
||
|
|
```sql
|
||
|
|
CREATE TABLE login_attempts (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
username TEXT NOT NULL,
|
||
|
|
ip_address TEXT,
|
||
|
|
success INTEGER DEFAULT 0,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
**account_lockouts**:
|
||
|
|
```sql
|
||
|
|
CREATE TABLE account_lockouts (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
user_id INTEGER NOT NULL,
|
||
|
|
locked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
unlock_at TIMESTAMP,
|
||
|
|
reason TEXT,
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
**active_sessions**:
|
||
|
|
```sql
|
||
|
|
CREATE TABLE active_sessions (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
user_id INTEGER NOT NULL,
|
||
|
|
session_token TEXT NOT NULL,
|
||
|
|
ip_address TEXT,
|
||
|
|
user_agent TEXT,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
expires_at TIMESTAMP,
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
**security_audit_log**:
|
||
|
|
```sql
|
||
|
|
CREATE TABLE security_audit_log (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
user_id INTEGER,
|
||
|
|
event_type TEXT NOT NULL,
|
||
|
|
status TEXT NOT NULL,
|
||
|
|
ip_address TEXT,
|
||
|
|
user_agent TEXT,
|
||
|
|
metadata TEXT,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Modified Users Table
|
||
|
|
|
||
|
|
Added fields:
|
||
|
|
- `password_changed_at`: Timestamp of last password change
|
||
|
|
- `password_expires_at`: Calculated password expiry date
|
||
|
|
- `failed_login_attempts`: Counter for failed attempts
|
||
|
|
- `last_failed_login`: Timestamp of last failed attempt
|
||
|
|
- `locked_until`: Account lockout expiry timestamp
|
||
|
|
- `last_login_at`: Timestamp of last successful login
|
||
|
|
- `last_login_ip`: IP address of last login
|
||
|
|
|
||
|
|
## Security Best Practices
|
||
|
|
|
||
|
|
### 1. Password Management
|
||
|
|
- ✅ Enforce strong password requirements
|
||
|
|
- ✅ Hash passwords with bcrypt (10 rounds)
|
||
|
|
- ✅ Prevent password reuse (last 5 passwords)
|
||
|
|
- ✅ Implement password expiry
|
||
|
|
- ✅ Provide password strength feedback
|
||
|
|
|
||
|
|
### 2. Account Protection
|
||
|
|
- ✅ Implement account lockout after failed attempts
|
||
|
|
- ✅ Rate limiting on authentication endpoints
|
||
|
|
- ✅ Two-factor authentication support
|
||
|
|
- ✅ Account activation/deactivation
|
||
|
|
- ✅ Secure password reset flow (to be implemented)
|
||
|
|
|
||
|
|
### 3. Session Security
|
||
|
|
- ✅ JWT tokens with expiration
|
||
|
|
- ✅ Session tracking and management
|
||
|
|
- ✅ Limit concurrent sessions
|
||
|
|
- ✅ Automatic session cleanup
|
||
|
|
- ✅ Session activity monitoring
|
||
|
|
|
||
|
|
### 4. Audit & Monitoring
|
||
|
|
- ✅ Comprehensive security event logging
|
||
|
|
- ✅ Track failed login attempts
|
||
|
|
- ✅ Log password changes
|
||
|
|
- ✅ Monitor 2FA events
|
||
|
|
- ✅ IP address and user agent tracking
|
||
|
|
- ✅ Automatic log retention management
|
||
|
|
|
||
|
|
### 5. API Security
|
||
|
|
- ✅ Rate limiting on sensitive endpoints
|
||
|
|
- ✅ Input validation with express-validator
|
||
|
|
- ✅ Parameterized SQL queries
|
||
|
|
- ✅ Proper error handling without information leakage
|
||
|
|
- ✅ Token-based authentication
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
### Test Password Policy
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test registration with weak password
|
||
|
|
curl -X POST http://localhost:5000/api/auth/check-password-strength \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"password": "weak"}'
|
||
|
|
|
||
|
|
# Test registration with strong password
|
||
|
|
curl -X POST http://localhost:5000/api/auth/check-password-strength \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"password": "SecureP@ssw0rd123!Strong"}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Test Account Lockout
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Attempt 6 failed logins
|
||
|
|
for i in {1..6}; do
|
||
|
|
curl -X POST http://localhost:5000/api/auth/login \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"username": "testuser", "password": "wrongpassword"}'
|
||
|
|
echo ""
|
||
|
|
done
|
||
|
|
```
|
||
|
|
|
||
|
|
### Test Security Status
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -X GET http://localhost:5000/api/auth/security-status \
|
||
|
|
-H "Authorization: Bearer YOUR_TOKEN"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Future Enhancements
|
||
|
|
|
||
|
|
### Planned Features
|
||
|
|
1. **Email Notifications**: Notify users of:
|
||
|
|
- Password expiry warnings
|
||
|
|
- Account lockouts
|
||
|
|
- Suspicious login attempts
|
||
|
|
- Password changes
|
||
|
|
|
||
|
|
2. **Advanced Session Management**:
|
||
|
|
- Session termination endpoint
|
||
|
|
- View all active sessions
|
||
|
|
- Revoke specific sessions
|
||
|
|
- Device fingerprinting
|
||
|
|
|
||
|
|
3. **Security Dashboard**: Admin panel showing:
|
||
|
|
- Failed login attempts by IP
|
||
|
|
- Locked accounts
|
||
|
|
- Password expiry reports
|
||
|
|
- Security event timeline
|
||
|
|
|
||
|
|
4. **IP Whitelisting/Blacklisting**:
|
||
|
|
- Automatic IP blocking after threshold
|
||
|
|
- Manual IP whitelist for trusted locations
|
||
|
|
- Geolocation-based access control
|
||
|
|
|
||
|
|
5. **Password Reset Flow**:
|
||
|
|
- Secure email-based reset
|
||
|
|
- Reset token expiration
|
||
|
|
- Rate limiting on reset requests
|
||
|
|
- Notification on password reset
|
||
|
|
|
||
|
|
6. **Biometric Authentication**:
|
||
|
|
- WebAuthn/FIDO2 support
|
||
|
|
- Fingerprint authentication
|
||
|
|
- Face ID support for mobile
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Account Locked
|
||
|
|
**Problem**: User cannot login due to lockout.
|
||
|
|
**Solution**:
|
||
|
|
- Wait for lockout duration to expire (30 minutes)
|
||
|
|
- Admin can manually clear lockout in database:
|
||
|
|
```sql
|
||
|
|
UPDATE users SET locked_until = NULL, failed_login_attempts = 0 WHERE username = 'username';
|
||
|
|
```
|
||
|
|
|
||
|
|
### Password Expired
|
||
|
|
**Problem**: User cannot login due to expired password.
|
||
|
|
**Solution**:
|
||
|
|
- User must use "Forgot Password" flow (when implemented)
|
||
|
|
- Admin can extend expiry:
|
||
|
|
```sql
|
||
|
|
UPDATE users SET password_expires_at = datetime('now', '+90 days') WHERE username = 'username';
|
||
|
|
```
|
||
|
|
|
||
|
|
### Too Many Sessions
|
||
|
|
**Problem**: User exceeds max concurrent sessions.
|
||
|
|
**Solution**:
|
||
|
|
- Oldest session automatically removed
|
||
|
|
- User can logout from other devices
|
||
|
|
- Admin can clear sessions:
|
||
|
|
```sql
|
||
|
|
DELETE FROM active_sessions WHERE user_id = X;
|
||
|
|
```
|
||
|
|
|
||
|
|
## Compliance
|
||
|
|
|
||
|
|
This implementation helps meet requirements for:
|
||
|
|
- **GDPR**: Audit logging, data protection
|
||
|
|
- **PCI DSS**: Password policies, session management
|
||
|
|
- **SOC 2**: Access controls, monitoring
|
||
|
|
- **ISO 27001**: Information security management
|
||
|
|
|
||
|
|
## Support
|
||
|
|
|
||
|
|
For issues or questions:
|
||
|
|
1. Check logs: `docker logs tv-backend`
|
||
|
|
2. Review security audit log in database
|
||
|
|
3. Consult this documentation
|
||
|
|
4. Contact system administrator
|