streamflow/docs/AUTHENTICATION_SECURITY.md

584 lines
13 KiB
Markdown
Raw Permalink Normal View History

# 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