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');
}
}