Security is crucial in Node.js apps. Let’s go step by step through Helmet.js, rate limiting, and input validation.
1️⃣ Helmet.js (HTTP Headers Security)
-
Helmet sets various HTTP headers to protect your app from common web vulnerabilities (XSS, clickjacking, MIME sniffing, etc.).
-
Easy to integrate in Express apps.
Installation
npm install helmet
Usage
const express = require("express");
const helmet = require("helmet");
const app = express();
app.use(helmet()); // adds multiple security headers by default
app.get("/", (req, res) => res.send("Secure App"));
Example Headers Added
-
Content-Security-Policy
→ prevents XSS attacks -
X-Frame-Options
→ prevents clickjacking -
X-Content-Type-Options
→ prevents MIME sniffing -
Referrer-Policy
→ controls referrer info
2️⃣ Rate Limiting & Throttling
-
Purpose: prevent abuse, brute-force attacks, and DDoS.
-
Limits the number of requests a client can make in a time window.
Using express-rate-limit
npm install express-rate-limit
Example
const rateLimit = require("express-rate-limit");
// Limit: 100 requests per 15 minutes per IP
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
message: "Too many requests, please try again later."
});
app.use(limiter);
- Can also apply per-route, e.g.,
/login
to prevent brute-force attacks.
3️⃣ Input Validation (Joi / express-validator)
- Purpose: validate incoming data to prevent bad data, SQL/NoSQL injections, or app crashes.
a) Using Joi
npm install joi
const Joi = require("joi");
const userSchema = Joi.object({
name: Joi.string().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required()
});
const validateUser = (req, res, next) => {
const { error } = userSchema.validate(req.body);
if (error) return res.status(400).json({ error: error.details[0].message });
next();
};
// Usage in route
app.post("/register", validateUser, registerController);
b) Using express-validator
npm install express-validator
const { body, validationResult } = require("express-validator");
app.post("/register",
body("name").isLength({ min: 3 }),
body("email").isEmail(),
body("password").isLength({ min: 6 }),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() });
next();
},
registerController
);
4️⃣ Best Practices
-
Combine Helmet + Rate Limiting + Validation → strong baseline security
-
Validate all user input (body, query, params)
-
Limit sensitive routes like
/login
and/signup
-
Keep dependencies updated → security patches are crucial
✅ Summary
Security Layer | Purpose | Tool/Library |
---|---|---|
HTTP headers protection | Prevent common web attacks | Helmet.js |
Rate limiting/throttling | Prevent brute-force & DDoS attacks | express-rate-limit |
Input validation | Ensure incoming data is correct & safe | Joi / express-validator |