416 lines
12 KiB
Markdown
416 lines
12 KiB
Markdown
|
|
# Session Management Security Implementation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
This document details the comprehensive session management security implementation for StreamFlow, addressing session fixation, session hijacking, and other session-based attacks through proper session handling, cookie security, and timeout enforcement.
|
||
|
|
|
||
|
|
## Session Security Features
|
||
|
|
|
||
|
|
### 1. Secure Session Creation
|
||
|
|
|
||
|
|
**Implementation:** `backend/middleware/securityEnhancements.js`
|
||
|
|
|
||
|
|
- **Cryptographically Strong Session IDs**: Sessions use JWT tokens signed with `JWT_SECRET`
|
||
|
|
- **Random Session Tokens**: Each session gets a unique, unpredictable token
|
||
|
|
- **Session Metadata**: Tracks user_id, IP address, user agent, timestamps
|
||
|
|
- **Absolute Timeout**: 24-hour maximum session lifetime (configurable)
|
||
|
|
- **Idle Timeout**: 2-hour inactivity limit (configurable)
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const SESSION_POLICY = {
|
||
|
|
maxConcurrentSessions: 3,
|
||
|
|
absoluteTimeout: 24, // hours
|
||
|
|
idleTimeout: 2, // hours
|
||
|
|
refreshTokenRotation: true
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. HTTP-Only Cookie Configuration
|
||
|
|
|
||
|
|
**Implementation:** `backend/routes/auth.js`
|
||
|
|
|
||
|
|
All authentication endpoints now set secure HTTP-only cookies:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
res.cookie('auth_token', token, {
|
||
|
|
httpOnly: true, // Prevents XSS access
|
||
|
|
secure: process.env.NODE_ENV === 'production', // HTTPS only in production
|
||
|
|
sameSite: 'strict', // CSRF protection
|
||
|
|
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
**Protected Endpoints:**
|
||
|
|
- `POST /api/auth/register` - Registration
|
||
|
|
- `POST /api/auth/login` - Standard login
|
||
|
|
- `POST /api/auth/verify-2fa` - Two-factor authentication (both TOTP and backup codes)
|
||
|
|
|
||
|
|
**Cookie Security Attributes:**
|
||
|
|
- **httpOnly**: JavaScript cannot access the cookie (prevents XSS)
|
||
|
|
- **secure**: Cookie only sent over HTTPS (prevents man-in-the-middle)
|
||
|
|
- **sameSite: strict**: Cookie not sent with cross-site requests (prevents CSRF)
|
||
|
|
- **maxAge**: Cookie expires after 7 days
|
||
|
|
|
||
|
|
### 3. Session Validation & Idle Timeout Enforcement
|
||
|
|
|
||
|
|
**Implementation:** `backend/middleware/auth.js`
|
||
|
|
|
||
|
|
The authentication middleware now performs comprehensive session validation:
|
||
|
|
|
||
|
|
1. **Token Verification**: Validates JWT signature and expiration
|
||
|
|
2. **Session Lookup**: Verifies session exists in database
|
||
|
|
3. **Absolute Timeout Check**: Ensures session hasn't exceeded 24-hour lifetime
|
||
|
|
4. **Idle Timeout Check**: Validates last activity within 2-hour window
|
||
|
|
5. **Activity Update**: Updates `last_activity` timestamp on each request
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Idle timeout check
|
||
|
|
const idleTimeMs = now - lastActivity;
|
||
|
|
const idleTimeoutMs = SESSION_POLICY.idleTimeout * 60 * 60 * 1000;
|
||
|
|
|
||
|
|
if (idleTimeMs > idleTimeoutMs) {
|
||
|
|
db.run('DELETE FROM active_sessions WHERE id = ?', [session.id]);
|
||
|
|
return res.status(401).json({
|
||
|
|
error: 'Session expired due to inactivity',
|
||
|
|
sessionExpired: true
|
||
|
|
});
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Session Management API
|
||
|
|
|
||
|
|
**Implementation:** `backend/routes/sessions.js`
|
||
|
|
|
||
|
|
New RESTful API for session management:
|
||
|
|
|
||
|
|
#### User Endpoints
|
||
|
|
|
||
|
|
**GET /api/sessions/my-sessions**
|
||
|
|
- View all active sessions for the current user
|
||
|
|
- Returns device info, IP address, last activity
|
||
|
|
- Identifies current session
|
||
|
|
|
||
|
|
**DELETE /api/sessions/:sessionId**
|
||
|
|
- Terminate a specific session
|
||
|
|
- Cannot terminate current session (prevents accidental logout)
|
||
|
|
- Logs security audit event
|
||
|
|
|
||
|
|
**POST /api/sessions/terminate-all-others**
|
||
|
|
- Terminate all sessions except the current one
|
||
|
|
- Useful after password change or security concern
|
||
|
|
- Returns count of terminated sessions
|
||
|
|
|
||
|
|
#### Admin Endpoints
|
||
|
|
|
||
|
|
**GET /api/sessions/all**
|
||
|
|
- View all active sessions across all users
|
||
|
|
- Requires admin role
|
||
|
|
- Includes user information
|
||
|
|
|
||
|
|
**POST /api/sessions/force-logout/:userId**
|
||
|
|
- Admin can force logout a specific user
|
||
|
|
- Terminates all sessions for that user
|
||
|
|
- Logs security audit event
|
||
|
|
|
||
|
|
**GET /api/sessions/stats**
|
||
|
|
- Session statistics (total active, per-user counts)
|
||
|
|
- Requires admin role
|
||
|
|
|
||
|
|
### 5. Session Management UI
|
||
|
|
|
||
|
|
**Implementation:** `frontend/src/components/SessionManagement.jsx`
|
||
|
|
|
||
|
|
User-facing interface for managing active sessions:
|
||
|
|
|
||
|
|
**Features:**
|
||
|
|
- View all active sessions with device/browser detection
|
||
|
|
- Shows IP address, last activity, creation time
|
||
|
|
- Highlights current session
|
||
|
|
- Terminate individual sessions
|
||
|
|
- Bulk terminate all other sessions
|
||
|
|
- Real-time session refresh
|
||
|
|
- Internationalized (EN/RO)
|
||
|
|
|
||
|
|
**Device Detection:**
|
||
|
|
- Identifies browsers (Chrome, Firefox, Safari, Edge)
|
||
|
|
- Detects device types (Desktop, Mobile, Tablet)
|
||
|
|
- Shows user agent details
|
||
|
|
|
||
|
|
**UI Integration:**
|
||
|
|
- Embedded in Settings page (`/settings`)
|
||
|
|
- Uses Material-UI components
|
||
|
|
- Security notifications via `SecurityNotificationProvider`
|
||
|
|
|
||
|
|
### 6. Logout with Session Cleanup
|
||
|
|
|
||
|
|
**Implementation:** `backend/routes/auth.js`
|
||
|
|
|
||
|
|
New logout endpoint with proper cleanup:
|
||
|
|
|
||
|
|
**POST /api/auth/logout**
|
||
|
|
- Requires authentication
|
||
|
|
- Removes session from database
|
||
|
|
- Clears HTTP-only cookie
|
||
|
|
- Logs security audit event
|
||
|
|
- Returns success confirmation
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Clear the HTTP-only cookie
|
||
|
|
res.clearCookie('auth_token', {
|
||
|
|
httpOnly: true,
|
||
|
|
secure: process.env.NODE_ENV === 'production',
|
||
|
|
sameSite: 'strict'
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## Attack Prevention
|
||
|
|
|
||
|
|
### Session Fixation Protection
|
||
|
|
|
||
|
|
1. **New Session on Login**: Fresh session created after successful authentication
|
||
|
|
2. **Token Regeneration**: JWT token signed with unique session data
|
||
|
|
3. **Old Session Cleanup**: Previous sessions can be terminated
|
||
|
|
4. **Session Binding**: Session tied to user_id, IP, and user agent
|
||
|
|
|
||
|
|
### Session Hijacking Prevention
|
||
|
|
|
||
|
|
1. **HTTP-Only Cookies**: JavaScript cannot access auth tokens
|
||
|
|
2. **HTTPS Enforcement**: `secure` flag in production prevents interception
|
||
|
|
3. **SameSite Strict**: Prevents CSRF by blocking cross-site cookies
|
||
|
|
4. **IP & User Agent Tracking**: Session metadata helps detect suspicious activity
|
||
|
|
5. **Idle Timeout**: Limits exposure window of stolen sessions
|
||
|
|
6. **Absolute Timeout**: Maximum 24-hour session lifetime
|
||
|
|
|
||
|
|
### Concurrent Session Control
|
||
|
|
|
||
|
|
1. **Max 3 Sessions**: `SESSION_POLICY.maxConcurrentSessions` enforced
|
||
|
|
2. **User Visibility**: Users can see all active sessions
|
||
|
|
3. **Selective Termination**: Users can kill suspicious sessions
|
||
|
|
4. **Bulk Termination**: "Terminate all others" for security incidents
|
||
|
|
|
||
|
|
## Database Schema
|
||
|
|
|
||
|
|
### active_sessions Table
|
||
|
|
|
||
|
|
```sql
|
||
|
|
CREATE TABLE IF NOT EXISTS active_sessions (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
user_id INTEGER NOT NULL,
|
||
|
|
session_token TEXT NOT NULL,
|
||
|
|
ip_address TEXT,
|
||
|
|
user_agent TEXT,
|
||
|
|
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
expires_at TIMESTAMP NOT NULL,
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users (id)
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
**Indexes:**
|
||
|
|
- `user_id` - Fast lookup of user sessions
|
||
|
|
- `session_token` - Fast session validation
|
||
|
|
- `expires_at` - Efficient cleanup of expired sessions
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
### Environment Variables
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# JWT Secret (CRITICAL - must be unique and secure)
|
||
|
|
JWT_SECRET=your_secure_random_string_here
|
||
|
|
|
||
|
|
# Session duration (optional, defaults below apply)
|
||
|
|
JWT_EXPIRES_IN=7d
|
||
|
|
|
||
|
|
# Environment (affects cookie security)
|
||
|
|
NODE_ENV=production
|
||
|
|
```
|
||
|
|
|
||
|
|
### Session Policy Configuration
|
||
|
|
|
||
|
|
**File:** `backend/utils/passwordPolicy.js`
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const SESSION_POLICY = {
|
||
|
|
maxConcurrentSessions: 3, // Maximum sessions per user
|
||
|
|
absoluteTimeout: 24, // Hours until forced logout
|
||
|
|
idleTimeout: 2, // Hours of inactivity before logout
|
||
|
|
refreshTokenRotation: true // Future: implement refresh token rotation
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## Automated Cleanup
|
||
|
|
|
||
|
|
**Implementation:** `backend/jobs/epgSync.js` (runs hourly)
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
setInterval(() => {
|
||
|
|
const { cleanupExpiredSessions } = require('../middleware/securityEnhancements');
|
||
|
|
cleanupExpiredSessions();
|
||
|
|
}, 60 * 60 * 1000); // Every hour
|
||
|
|
```
|
||
|
|
|
||
|
|
**Cleanup Process:**
|
||
|
|
1. Deletes sessions where `expires_at < NOW()`
|
||
|
|
2. Runs automatically every hour
|
||
|
|
3. Prevents database bloat
|
||
|
|
4. Logs cleanup count
|
||
|
|
|
||
|
|
## Internationalization
|
||
|
|
|
||
|
|
### Translation Keys (EN/RO)
|
||
|
|
|
||
|
|
Added to `frontend/src/locales/en.json` and `ro.json`:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"security": {
|
||
|
|
"activeSessions": "Active Sessions",
|
||
|
|
"terminateSession": "Terminate Session",
|
||
|
|
"terminateAllSessions": "Terminate All Other Sessions",
|
||
|
|
"multipleDevices": "You are currently logged in on {{count}} devices",
|
||
|
|
"noRecentActivity": "No recent activity found",
|
||
|
|
"ipAddress": "IP Address",
|
||
|
|
"status": "Status"
|
||
|
|
},
|
||
|
|
"device": "Device",
|
||
|
|
"location": "Location",
|
||
|
|
"lastActive": "Last Active",
|
||
|
|
"created": "Created",
|
||
|
|
"current": "Current",
|
||
|
|
"active": "Active",
|
||
|
|
"actions": "Actions",
|
||
|
|
"refresh": "Refresh"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Recommendations
|
||
|
|
|
||
|
|
### Manual Testing
|
||
|
|
|
||
|
|
1. **Session Creation**
|
||
|
|
```bash
|
||
|
|
# Login and verify cookie is set
|
||
|
|
curl -c cookies.txt -X POST http://localhost:3000/api/auth/login \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"username":"test","password":"password"}'
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **View Active Sessions**
|
||
|
|
```bash
|
||
|
|
curl -b cookies.txt http://localhost:3000/api/sessions/my-sessions
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Idle Timeout**
|
||
|
|
- Login
|
||
|
|
- Wait 2+ hours without making requests
|
||
|
|
- Next request should return 401 with `sessionExpired: true`
|
||
|
|
|
||
|
|
4. **Absolute Timeout**
|
||
|
|
- Login
|
||
|
|
- Keep session active (make requests every hour)
|
||
|
|
- After 24 hours, session should expire
|
||
|
|
|
||
|
|
5. **Session Termination**
|
||
|
|
- Login from multiple devices
|
||
|
|
- Terminate one session
|
||
|
|
- Verify terminated session gets 401
|
||
|
|
|
||
|
|
6. **Cookie Security**
|
||
|
|
- Verify cookies in browser DevTools have `HttpOnly`, `Secure` (production), `SameSite=Strict`
|
||
|
|
|
||
|
|
### Automated Testing
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Example test for idle timeout
|
||
|
|
describe('Session Idle Timeout', () => {
|
||
|
|
it('should expire session after 2 hours of inactivity', async () => {
|
||
|
|
const token = await loginUser('test', 'password');
|
||
|
|
|
||
|
|
// Fast-forward time 2+ hours
|
||
|
|
await setSystemTime(Date.now() + (2.5 * 60 * 60 * 1000));
|
||
|
|
|
||
|
|
const response = await fetch('/api/playlists', {
|
||
|
|
headers: { Authorization: `Bearer ${token}` }
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.status).toBe(401);
|
||
|
|
expect(response.body.sessionExpired).toBe(true);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## Security Audit Logging
|
||
|
|
|
||
|
|
All session events are logged via `SecurityAuditLogger`:
|
||
|
|
|
||
|
|
- **login** - Successful authentication
|
||
|
|
- **logout** - User-initiated logout
|
||
|
|
- **session_terminated** - Session killed by user
|
||
|
|
- **session_force_logout** - Admin force logout
|
||
|
|
- **session_expired_idle** - Idle timeout triggered
|
||
|
|
- **session_expired_absolute** - Absolute timeout triggered
|
||
|
|
|
||
|
|
**Audit Log Query:**
|
||
|
|
```sql
|
||
|
|
SELECT * FROM security_audit_log
|
||
|
|
WHERE event_type LIKE '%session%'
|
||
|
|
ORDER BY created_at DESC
|
||
|
|
LIMIT 100;
|
||
|
|
```
|
||
|
|
|
||
|
|
## Deployment Checklist
|
||
|
|
|
||
|
|
- [ ] Set strong `JWT_SECRET` in production
|
||
|
|
- [ ] Enable `NODE_ENV=production` for secure cookies
|
||
|
|
- [ ] Configure HTTPS/TLS for production
|
||
|
|
- [ ] Verify session cleanup job is running
|
||
|
|
- [ ] Test idle timeout in production environment
|
||
|
|
- [ ] Monitor session count per user
|
||
|
|
- [ ] Review security audit logs regularly
|
||
|
|
- [ ] Set up alerts for suspicious session activity
|
||
|
|
|
||
|
|
## Future Enhancements
|
||
|
|
|
||
|
|
### Planned Features
|
||
|
|
|
||
|
|
1. **Refresh Token Rotation**
|
||
|
|
- Implement short-lived access tokens
|
||
|
|
- Long-lived refresh tokens
|
||
|
|
- Automatic token rotation
|
||
|
|
|
||
|
|
2. **Session Fingerprinting**
|
||
|
|
- Enhanced device fingerprinting
|
||
|
|
- Detect session hijacking via fingerprint changes
|
||
|
|
- Challenge suspicious sessions
|
||
|
|
|
||
|
|
3. **Geographic Session Restrictions**
|
||
|
|
- IP geolocation tracking
|
||
|
|
- Alert on login from new locations
|
||
|
|
- Option to restrict sessions by country
|
||
|
|
|
||
|
|
4. **Session Analytics**
|
||
|
|
- Dashboard showing session trends
|
||
|
|
- Average session duration
|
||
|
|
- Peak usage times
|
||
|
|
- Device distribution
|
||
|
|
|
||
|
|
5. **Trusted Device Management**
|
||
|
|
- Remember trusted devices
|
||
|
|
- Extended timeouts for trusted devices
|
||
|
|
- Device verification via email
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)
|
||
|
|
- [RFC 6265 - HTTP State Management Mechanism (Cookies)](https://tools.ietf.org/html/rfc6265)
|
||
|
|
- [SameSite Cookie Attribute Explained](https://web.dev/samesite-cookies-explained/)
|
||
|
|
|
||
|
|
## Support
|
||
|
|
|
||
|
|
For questions or issues related to session management:
|
||
|
|
- Review this documentation
|
||
|
|
- Check security audit logs
|
||
|
|
- Examine `active_sessions` table
|
||
|
|
- Enable debug logging in `backend/utils/logger.js`
|