Implementing Secure Authentication Headers

Implementing Secure Authentication Headers

Complete Authentication Security Implementation

class AuthenticationSecurity {
    constructor(config) {
        this.config = {
            sessionTimeout: config.sessionTimeout || 3600000, // 1 hour
            absoluteTimeout: config.absoluteTimeout || 86400000, // 24 hours
            csrfProtection: config.csrfProtection !== false,
            fingerprintValidation: config.fingerprintValidation !== false
        };
    }
    
    // Secure session creation
    createSecureSession(req, res, user) {
        // Generate session fingerprint
        const fingerprint = this.generateFingerprint(req);
        
        // Set session data
        req.session.userId = user.id;
        req.session.fingerprint = fingerprint;
        req.session.createdAt = Date.now();
        req.session.lastActivity = Date.now();
        
        // Set security headers
        this.setAuthenticationHeaders(res);
        
        // Set CSRF token if enabled
        if (this.config.csrfProtection) {
            const csrfToken = this.generateCSRFToken();
            req.session.csrfToken = csrfToken;
            res.setHeader('X-CSRF-Token', csrfToken);
        }
        
        // Set additional security cookies
        res.cookie('__Secure-Fingerprint', fingerprint, {
            secure: true,
            httpOnly: true,
            sameSite: 'strict',
            maxAge: this.config.sessionTimeout
        });
    }
    
    // Generate browser fingerprint
    generateFingerprint(req) {
        const crypto = require('crypto');
        const components = [
            req.headers['user-agent'],
            req.headers['accept-language'],
            req.headers['accept-encoding'],
            req.ip
        ];
        
        return crypto
            .createHash('sha256')
            .update(components.join('|'))
            .digest('hex');
    }
    
    // Session validation middleware
    validateSession() {
        return (req, res, next) => {
            if (!req.session || !req.session.userId) {
                return res.status(401).json({ error: 'No active session' });
            }
            
            // Check session timeout
            const now = Date.now();
            const lastActivity = req.session.lastActivity || 0;
            const createdAt = req.session.createdAt || 0;
            
            if (now - lastActivity > this.config.sessionTimeout) {
                req.session.destroy();
                res.setHeader('Clear-Site-Data', '"cookies"');
                return res.status(401).json({ error: 'Session timeout' });
            }
            
            if (now - createdAt > this.config.absoluteTimeout) {
                req.session.destroy();
                res.setHeader('Clear-Site-Data', '"cookies"');
                return res.status(401).json({ error: 'Session expired' });
            }
            
            // Validate fingerprint
            if (this.config.fingerprintValidation) {
                const currentFingerprint = this.generateFingerprint(req);
                if (req.session.fingerprint !== currentFingerprint) {
                    req.session.destroy();
                    res.setHeader('Clear-Site-Data', '"cookies", "storage"');
                    return res.status(401).json({ error: 'Session validation failed' });
                }
            }
            
            // Update last activity
            req.session.lastActivity = now;
            
            // Rotate session ID periodically
            if (now - lastActivity > 300000) { // 5 minutes
                req.session.regenerate((err) => {
                    if (err) {
                        console.error('Session regeneration error:', err);
                    }
                });
            }
            
            // Set security headers
            this.setAuthenticationHeaders(res);
            
            next();
        };
    }
    
    // Set authentication-related security headers
    setAuthenticationHeaders(res) {
        // Prevent caching of authenticated content
        res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate, max-age=0');
        res.setHeader('Pragma', 'no-cache');
        res.setHeader('Expires', '0');
        
        // Additional security headers
        res.setHeader('X-Content-Type-Options', 'nosniff');
        res.setHeader('X-Frame-Options', 'DENY');
        res.setHeader('Content-Security-Policy', 
            "default-src 'self'; " +
            "script-src 'self' 'nonce-" + res.locals.nonce + "'; " +
            "style-src 'self' 'unsafe-inline'; " +
            "img-src 'self' data: https:; " +
            "connect-src 'self'; " +
            "frame-ancestors 'none'; " +
            "form-action 'self';"
        );
    }
    
    // CSRF token generation
    generateCSRFToken() {
        return require('crypto').randomBytes(32).toString('hex');
    }
}