How to secure an Express.js application?
Security in Express.js
Securing an Express.js API requires a combination of packages and best practices. Here are the most important layers of security.
1. Helmet β HTTP Security Headers
bash
npm install helmetjs
const helmet = require('helmet');
// Sets 11 security-related HTTP headers automatically
app.use(helmet());
// What helmet sets:
// Content-Security-Policy
// X-Frame-Options: DENY
// X-Content-Type-Options: nosniff
// Strict-Transport-Security (HSTS)
// X-XSS-Protection
// Referrer-Policy
// ...and more2. Rate Limiting
bash
npm install express-rate-limitjs
const rateLimit = require('express-rate-limit');
// General API rate limit
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // max 100 requests per window
standardHeaders: true,
legacyHeaders: false,
message: { error: 'Too many requests, please try again later' }
});
// Stricter limit for auth routes
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // only 5 login attempts per 15 min
skipSuccessfulRequests: true,
message: { error: 'Too many login attempts' }
});
app.use('/api/', apiLimiter);
app.use('/auth/login', authLimiter);
app.use('/auth/register', authLimiter);3. Input Sanitization
bash
npm install express-mongo-sanitize xss-cleanjs
const mongoSanitize = require('express-mongo-sanitize');
const xss = require('xss-clean');
app.use(mongoSanitize()); // prevent NoSQL injection: $where, $gt
app.use(xss()); // strip HTML tags from input4. Request Size Limits
js
app.use(express.json({ limit: '10kb' })); // limit JSON body size
app.use(express.urlencoded({ limit: '10kb', extended: true }));5. HTTPS & HSTS
js
// Force HTTPS redirect in production
app.use((req, res, next) => {
if (process.env.NODE_ENV === 'production' && !req.secure) {
return res.redirect(301, `https://${req.hostname}${req.url}`);
}
next();
});6. Environment Variables
js
// β
Good β secrets in environment
const JWT_SECRET = process.env.JWT_SECRET;
const DB_PASSWORD = process.env.DB_PASSWORD;
// β Bad β secrets in code
const JWT_SECRET = 'hardcoded-secret';7. Prevent Parameter Pollution
bash
npm install hppjs
const hpp = require('hpp');
app.use(hpp()); // prevent: /api?sort=name&sort=price8. Hide Express Signature
js
app.disable('x-powered-by');
// or use helmet() which does this automatically
// Removes: X-Powered-By: Express headerSecurity Checklist
| # | Item | Package |
|---|---|---|
| β | HTTP security headers | helmet |
| β | Rate limiting | express-rate-limit |
| β | CORS configuration | cors |
| β | Input sanitization | express-mongo-sanitize, xss-clean |
| β | Request size limits | express.json({ limit }) |
| β | JWT with short expiry | jsonwebtoken |
| β | Password hashing | bcryptjs (12+ rounds) |
| β | HTTPS enforcement | nginx / redirect middleware |
| β | Hide X-Powered-By | helmet |
| β | Secrets in env vars | dotenv |
Summary
Security is layered: start with helmet and rate limiting, validate and sanitize all inputs, enforce HTTPS, use strong password hashing, and keep secrets in environment variables. Never trust client data.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.