Security Best Practices
// 1. Helmet for security headers\nconst helmet = require('helmet');\napp.use(helmet());\n\n// 2. Rate limiting\nconst rateLimit = require('express-rate-limit');\nconst limiter = rateLimit({\n windowMs: 15 * 60 * 1000, // 15 minutes\n max: 100, // max 100 requests per window\n message: { error: 'Too many requests' },\n});\napp.use('/api/', limiter);\n\n// 3. Input validation (prevent injection)\nconst cleanInput = (input) => {\n if (typeof input !== 'string') return input;\n return input.replace(/<[^>]*>/g, '').trim();\n};\n\n// 4. SQL injection prevention (use parameterized queries)\n// BAD: const query = `SELECT * FROM users WHERE id = ${id}`;\n// GOOD: knex('users').where({ id })\n\n// 5. CORS configuration\nconst cors = require('cors');\napp.use(cors({\n origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',\n credentials: true,\n maxAge: 86400,\n}));\n\n// 6. Environment variables for secrets\n// .env file with dotenv\nrequire('dotenv').config();\n\n// 7. HTTPS enforcement\nif (process.env.NODE_ENV === 'production') {\n app.use((req, res, next) => {\n if (!req.secure) return res.redirect(`https://${req.headers.host}${req.url}`);\n next();\n });\n}
Common Vulnerabilities
- XSS: Sanitize user input, use helmet
- CSRF: Use csurf middleware or SameSite cookies
- SQL Injection: Use parameterized queries/ORM
- DoS: Rate limiting, body size limits
- Broken Auth: Proper session/token management
Examples
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const cors = require('cors');
const express = require('express');
const app = express();
// Security middleware stack
app.use(helmet()); // Security headers
app.use(cors({ origin: process.env.CORS_ORIGIN })); // CORS
// Rate limiting per route group
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // 5 login attempts per 15 min
message: { error: 'Too many login attempts' },
});
app.use('/api/login', authLimiter);
// Input sanitization middleware
app.use((req, res, next) => {
if (req.body) {
for (const key of Object.keys(req.body)) {
if (typeof req.body[key] === 'string') {
req.body[key] = req.body[key].replace(/<script[^>]*>.*<\/script>/gi, '');
}
}
}
next();
});
app.use(express.json({ limit: '1mb' })); // Limit body size
console.log('Security measures applied');