Skip to main content
Practice Problems

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 helmet
js
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 more

2. Rate Limiting

bash
npm install express-rate-limit
js
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-clean
js
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 input

4. 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 hpp
js
const hpp = require('hpp'); app.use(hpp()); // prevent: /api?sort=name&sort=price

8. Hide Express Signature

js
app.disable('x-powered-by'); // or use helmet() which does this automatically // Removes: X-Powered-By: Express header

Security Checklist

#ItemPackage
βœ…HTTP security headershelmet
βœ…Rate limitingexpress-rate-limit
βœ…CORS configurationcors
βœ…Input sanitizationexpress-mongo-sanitize, xss-clean
βœ…Request size limitsexpress.json({ limit })
βœ…JWT with short expiryjsonwebtoken
βœ…Password hashingbcryptjs (12+ rounds)
βœ…HTTPS enforcementnginx / redirect middleware
βœ…Hide X-Powered-Byhelmet
βœ…Secrets in env varsdotenv

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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems