Security Hardening: Helmet, CORS, Express Rate Limiting & HPP0%
Security Hardening: Helmet, CORS, Express Rate Limiting & HPP
Beginner12 min read•Updated: Jul 11, 2026
Security Hardening: Helmet, CORS, Express Rate Limiting & HPP
Exposing an unhardened Express.js backend directly to the public internet invites automated bot attacks, DDoS floods, clickjacking, cross-site request forgery, and parameter pollution. Hardening your application with four industry-standard security middleware packages is mandatory for every production deployment.
1. The 4 Security Pillars
- 1Helmet (
helmet): Secures Express apps by setting 15+ HTTP response headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options). - 2CORS (
cors): Restricts cross-origin resource sharing so that only your designated frontend domains can access the API. - 3Rate Limiting (
express-rate-limit): Throttles repetitive requests from identical IP addresses, thwarting brute-force login attacks and DoS floods. - 4HPP (
hpp): Protects against HTTP Parameter Pollution attacks where attackers duplicate query parameters to bypass filters.
2. Production Security Configuration
JavaScript
import express from 'express';
import helmet from 'helmet';
import cors from 'cors';
import rateLimit from 'express-rate-limit';
import hpp from 'hpp';
const app = express();
// 1. HELMET: Set security HTTP headers
app.use(helmet());
// 2. CORS: Restrict API access to trusted frontend origins
const allowedOrigins = ['https://mskinstitute.com', 'https://admin.mskinstitute.com'];
app.use(cors({
origin: (origin, callback) => {
// Allow requests with no origin (e.g. mobile apps, curl) or matched domains
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Blocked by CORS policy'));
}
},
credentials: true, // Allow cookies across origins
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
}));
// 3. RATE LIMITING: Global and Route-Specific Throttling
const globalLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 300, // Max 300 requests per IP per window
message: { error: 'Too many requests from this IP, please try again after 15 minutes.' },
standardHeaders: true, // Return RateLimit-* headers
legacyHeaders: false
});
app.use('/api', globalLimiter);
// Strict limiter for sensitive authentication endpoints
const authLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour
max: 10, // Only 10 failed login attempts per hour per IP!
message: { error: 'Too many login attempts. Account temporarily locked for 1 hour.' }
});
app.use('/api/v1/auth/login', authLimiter);
// 4. Body parsing
app.use(express.json({ limit: '10kb' })); // Mitigate body flood attacks
// 5. HPP: Prevent HTTP Parameter Pollution (e.g. ?sort=name&sort=price)
app.use(hpp({
whitelist: ['price', 'ratings', 'category'] // Allow duplicates for specific filter fields
}));
Interactive Quiz
Multiple Choice Questions
Question 1
What is the primary purpose of the
helmet package in an Express.js application?Question 2
Why should an authentication route like
/api/auth/login have a dedicated, strict rate limiter?Question 3
What does CORS (Cross-Origin Resource Sharing) control?
Question 4
What vulnerability does the
hpp (HTTP Parameter Pollution) middleware prevent?Question 5
What HTTP response status code is returned when a client exceeds the threshold set by
express-rate-limit?Next Lesson
Production Configuration, Environment Variables & PM2 Process Manager
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.