Chapter 11: Security Best Practices
Chapter 11 of 15
Chapter 11: Security Best Practices
11.1 Security Headers
Security headers protect applications from common vulnerabilities and attacks.
const helmet = require('helmet');
app.use(helmet());
// Custom security headers
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Strict-Transport-Security', 'max-age=31536000');
next();
});
11.2 Input Validation
const { body, validationResult } = require('express-validator');
app.post('/users',
body('email').isEmail(),
body('password').isLength({ min: 8 }),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Process request
}
);
11.3 Authentication and Authorization
// JWT authentication
const jwt = require('jsonwebtoken');
function generateToken(user) {
return jwt.sign(
{ userId: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: '24h' }
);
}
function verifyToken(token) {
return jwt.verify(token, process.env.JWT_SECRET);
}
// Password hashing
const bcrypt = require('bcrypt');
const hashedPassword = await bcrypt.hash(password, 10);
const isValid = await bcrypt.compare(password, hashedPassword);
11.4 SQL Injection Prevention
// Use parameterized queries
// Bad
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Good
const query = 'SELECT * FROM users WHERE email = ?';
const [rows] = await pool.execute(query, [email]);
11.5 Rate Limiting
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // Limit each IP to 100 requests per windowMs
});
app.use('/api/', limiter);