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

  1. Combine Helmet + Rate Limiting + Validation → strong baseline security

  2. Validate all user input (body, query, params)

  3. Limit sensitive routes like /login and /signup

  4. Keep dependencies updated → security patches are crucial


✅ Summary

Security LayerPurposeTool/Library
HTTP headers protectionPrevent common web attacksHelmet.js
Rate limiting/throttlingPrevent brute-force & DDoS attacksexpress-rate-limit
Input validationEnsure incoming data is correct & safeJoi / express-validator