Skip to content
BackendExpressJsNodeJs

10. Express Security – Helmet, CORS, Rate Limiting, Validation (2026)

April 25, 2026 19 min read

नमस्ते दोस्तों! 🙏
स्वागत है The Easy Master पर!

क्या तुमने कभी सोचा है – Express.js app ko secure kaise karein? XSS, CSRF, SQL Injection, Brute Force attacks – इनसे कैसे बचें?

Jab tum app production में deploy karte ho, toh security sabse important हो जाती है। Hackers tumhare app par attacks kar sakte hain – data steal कर सकते हैं, server crash कर सकते हैं।

Express security Helmet CORS rate limiting validation Hindi में समझना बहुत जरूरी है क्योंकि:

  • Security vulnerabilities app को destroy कर सकती हैं
  • User data protect करना है
  • Industry standards follow करने हैं
  • Interview mein pakka security questions puche jayenge
  • Every production app needs security middleware

Aaj kya seekhoge?

TopicKya Seekhega?
HelmetSecurity headers set karna
CORSCross-origin requests control
Rate LimitingBrute force attacks se bachna
Input ValidationSQL Injection, XSS se bachna
XSS ProtectionCross-site scripting
CSRF ProtectionCross-site request forgery
SQL InjectionParameterized queries
Best PracticesProduction security checklist

Kya tumhe pata hai?
Helmet 11 different security headers automatically set kar deta है – ek line mein!

तो चलिए शुरू करते हैं – Express security Helmet CORS rate limiting validation Hindi सीखने का सफर! 🚀

1. Express Security – Introduction

Web security attacks से app को बचाने के लिए measures हैं।

Common Web Attacks:

AttackDescriptionImpact
XSSMalicious scripts injectData steal, session hijack
CSRFUnauthorized requestsAction without consent
SQL InjectionMalicious SQL queriesDatabase access
Brute ForceMany login attemptsAccount takeover
DDoSMany requestsServer crash
MITMIntercept communicationData leak

Security Layers:

Code
SECURITY LAYERS FLOW

Client Request
      │
      ▼
1. Helmet (Security Headers)
   - XSS Protection
   - CSP (Content Security Policy)
   - HSTS
      │
      ▼
2. CORS (Cross-Origin Resource Sharing)
   - Allow / Block Domains
      │
      ▼
3. Rate Limiting
   - Limit Requests per IP
      │
      ▼
4. Input Validation
   - Sanitize
   - Validate
   - Escape
      │
      ▼
5. Route Handler
   - Business Logic Execution

Express security Helmet CORS rate limiting validation Hindi में हम सभी layers cover करेंगे।

2. Helmet – Security Headers

Helmet Express middleware है जो security headers automatically set करता है।

Installation:

Code
npm install helmet

Basic Setup:

Code
// server.js
const express = require('express');
const helmet = require('helmet');

const app = express();

// Apply helmet to all routes
app.use(helmet());

// Or with custom configuration
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      scriptSrc: ["'self'", "https://cdnjs.cloudflare.com"],
      imgSrc: ["'self'", "data:", "https:"],
      fontSrc: ["'self'", "https://fonts.googleapis.com"],
      connectSrc: ["'self'"],
    },
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  frameguard: {
    action: 'deny'
  },
  referrerPolicy: {
    policy: 'strict-origin-when-cross-origin'
  }
}));

What Headers Does Helmet Set?

HeaderPurpose
X-DNS-Prefetch-ControlDNS prefetch control
X-Frame-OptionsClickjacking protection
X-Content-Type-OptionsMIME type sniffing prevention
X-XSS-ProtectionXSS protection
Strict-Transport-SecurityHTTPS enforcement
Content-Security-PolicyResource whitelist
Referrer-PolicyReferrer info control

Helmet Configuration Options:

Code
// Disable specific middleware
app.use(helmet({
  contentSecurityPolicy: false,  // Disable CSP
  frameguard: false               // Disable frameguard
}));

// Or use individual middleware
app.use(require('helmet')());
app.use(require('helmet').contentSecurityPolicy());
app.use(require('helmet').crossOriginEmbedderPolicy());
app.use(require('helmet').crossOriginOpenerPolicy());
app.use(require('helmet').crossOriginResourcePolicy());
app.use(require('helmet').dnsPrefetchControl());
app.use(require('helmet').expectCt());
app.use(require('helmet').frameguard());
app.use(require('helmet').hidePoweredBy());
app.use(require('helmet').hsts());
app.use(require('helmet').ieNoOpen());
app.use(require('helmet').noSniff());
app.use(require('helmet').originAgentCluster());
app.use(require('helmet').permittedCrossDomainPolicies());
app.use(require('helmet').referrerPolicy());
app.use(require('helmet').xssFilter());

Content Security Policy (CSP) Detailed:

Code
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: [
      "'self'",
      "'unsafe-inline'",
      "https://cdn.jsdelivr.net",
      "https://code.jquery.com"
    ],
    styleSrc: [
      "'self'",
      "'unsafe-inline'",
      "https://fonts.googleapis.com"
    ],
    imgSrc: ["'self'", "data:", "https://images.example.com"],
    fontSrc: ["'self'", "https://fonts.gstatic.com"],
    connectSrc: ["'self'", "https://api.example.com"],
    frameSrc: ["'none'"],
    objectSrc: ["'none'"],
    upgradeInsecureRequests: [],
    reportUri: '/csp-report'
  },
  reportOnly: false // Set to true for testing
}));

3. CORS – Cross-Origin Resource Sharing

CORS control करता है कि कौन से domains tumhare API को access कर सकते हैं।

Installation:

Code
npm install cors

Basic Setup:

Code
const express = require('express');
const cors = require('cors');

const app = express();

// Allow all origins (not recommended for production)
app.use(cors());

// Or specific configuration
app.use(cors({
  origin: 'https://myfrontend.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  optionsSuccessStatus: 200
}));

CORS Configuration Options:

Code
// Allow multiple origins
const allowedOrigins = [
  'https://myfrontend.com',
  'https://admin.myfrontend.com',
  'http://localhost:3000'
];

app.use(cors({
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
  exposedHeaders: ['X-Total-Count', 'X-RateLimit-Limit'],
  credentials: true,
  maxAge: 86400 // 24 hours
}));

Route-specific CORS:

Code
// Public routes (no CORS restrictions)
app.get('/api/public', (req, res) => {
  res.json({ message: 'Public data' });
});

// Specific CORS for a route
app.get('/api/specific', cors({
  origin: 'https://specific-domain.com'
}), (req, res) => {
  res.json({ message: 'Specific CORS' });
});

// Preflight OPTIONS request handling
app.options('/api/secure', cors({
  origin: 'https://trusted.com',
  methods: ['POST', 'PUT', 'DELETE']
}));

CORS with Express Router:

Code
// routes/api.js
const express = require('express');
const router = express.Router();
const cors = require('cors');

const apiCors = cors({
  origin: process.env.API_CORS_ORIGIN,
  credentials: true
});

router.use(apiCors);

router.get('/data', (req, res) => {
  res.json({ data: 'Protected API data' });
});

module.exports = router;

4. Rate Limiting – Brute Force Protection

Rate limiting IP address के हिसाब से request count limit करता है।

Installation:

Code
npm install express-rate-limit

Basic Setup:

Code
const rateLimit = require('express-rate-limit');

// General rate limiter
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP, please try again later.',
  standardHeaders: true, // Return rate limit info in headers
  legacyHeaders: false // Disable X-RateLimit-* headers
});

// Apply to all routes
app.use(limiter);

Different Limiters for Different Routes:

Code
// Strict limiter for auth routes (login, register)
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // 5 attempts per 15 minutes
  message: 'Too many login attempts, please try again later.',
  skipSuccessfulRequests: true // Don't count successful requests
});

// Lighter limiter for public routes
const publicLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 30,
  message: 'Too many requests, please slow down.'
});

// API routes limiter
const apiLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 60,
  message: { error: 'Rate limit exceeded. Please wait.' }
});

// Apply different limiters
app.use('/api/auth', authLimiter);
app.use('/api/public', publicLimiter);
app.use('/api', apiLimiter);

Advanced Rate Limiting:

Code
// Store with Redis (for distributed apps)
const RedisStore = require('rate-limit-redis');
const redisClient = require('redis').createClient();

const limiter = rateLimit({
  store: new RedisStore({
    sendCommand: (...args) => redisClient.sendCommand(args),
  }),
  windowMs: 15 * 60 * 1000,
  max: 100,
  keyGenerator: (req) => {
    // Use IP + user ID for authenticated users
    return req.user ? `${req.ip}-${req.user.id}` : req.ip;
  },
  skip: (req) => {
    // Skip rate limiting for admin users
    return req.user && req.user.role === 'admin';
  },
  handler: (req, res) => {
    res.status(429).json({
      error: 'Too many requests',
      message: 'Please try again later',
      retryAfter: Math.ceil(req.rateLimit.resetTime - Date.now() / 1000)
    });
  }
});

Custom Rate Limiter with Database:

Code
// middleware/rateLimiter.js
const RateLimit = require('../models/RateLimit');

const customRateLimiter = (windowMs = 900000, max = 100) => {
  return async (req, res, next) => {
    const ip = req.ip;
    const endpoint = req.route?.path || req.path;
    const key = `${ip}:${endpoint}`;
    
    let record = await RateLimit.findOne({ key });
    
    if (!record) {
      record = new RateLimit({
        key,
        count: 1,
        expiresAt: new Date(Date.now() + windowMs)
      });
      await record.save();
      return next();
    }
    
    if (record.count >= max) {
      return res.status(429).json({
        error: 'Too many requests',
        retryAfter: Math.ceil((record.expiresAt - Date.now()) / 1000)
      });
    }
    
    record.count++;
    await record.save();
    next();
  };
};

module.exports = customRateLimiter;

5. Input Validation – SQL Injection & XSS Protection

Input validation malicious data को database तक पहुंचने से रोकता है।

Installation:

Code
npm install express-validator

Basic Validation:

Code
const { body, validationResult } = require('express-validator');

app.post('/api/users',
  // Validation rules
  body('email').isEmail().normalizeEmail(),
  body('password').isLength({ min: 6 }),
  body('name').trim().isLength({ min: 2 }).escape(),
  body('age').optional().isInt({ min: 18, max: 120 }),
  
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    
    // Safe to use validated data
    const { email, password, name, age } = req.body;
    // Create user...
    res.status(201).json({ message: 'User created' });
  }
);

Complete Validation Middleware:

Code
// middleware/validation.js
const { body, param, query, validationResult } = require('express-validator');

// User validation rules
const userValidation = {
  register: [
    body('name')
      .trim()
      .isLength({ min: 2, max: 50 })
      .withMessage('Name must be between 2 and 50 characters')
      .escape(),
    body('email')
      .isEmail()
      .normalizeEmail()
      .withMessage('Valid email is required'),
    body('password')
      .isLength({ min: 6 })
      .withMessage('Password must be at least 6 characters')
      .matches(/^(?=.*[A-Za-z])(?=.*\d)/)
      .withMessage('Password must contain at least one letter and one number'),
    body('age')
      .optional()
      .isInt({ min: 18, max: 120 })
      .withMessage('Age must be between 18 and 120')
  ],
  
  login: [
    body('email').isEmail().normalizeEmail(),
    body('password').notEmpty()
  ],
  
  updateProfile: [
    body('name').optional().trim().isLength({ min: 2 }).escape(),
    body('email').optional().isEmail().normalizeEmail(),
    body('bio').optional().trim().isLength({ max: 500 }).escape()
  ],
  
  id: [
    param('id').isInt().withMessage('Invalid ID format')
  ]
};

// Product validation
const productValidation = {
  create: [
    body('name').trim().isLength({ min: 3 }).escape(),
    body('price').isFloat({ min: 0 }).withMessage('Price must be positive'),
    body('category').optional().isIn(['electronics', 'clothing', 'books']),
    body('description').optional().trim().isLength({ max: 1000 }).escape()
  ]
};

// Sanitization middleware
const sanitizeInput = (req, res, next) => {
  if (req.body) {
    // Remove HTML tags
    for (let key in req.body) {
      if (typeof req.body[key] === 'string') {
        req.body[key] = req.body[key].replace(/<[^>]*>/g, '');
      }
    }
  }
  next();
};

// Validation result handler
const validate = (validations) => {
  return async (req, res, next) => {
    await Promise.all(validations.map(validation => validation.run(req)));
    
    const errors = validationResult(req);
    if (errors.isEmpty()) {
      return next();
    }
    
    res.status(400).json({
      success: false,
      errors: errors.array().map(err => ({
        field: err.param,
        message: err.msg
      }))
    });
  };
};

module.exports = { userValidation, productValidation, sanitizeInput, validate };

Using Validation:

Code
// routes/users.js
const express = require('express');
const router = express.Router();
const { userValidation, validate } = require('../middleware/validation');

router.post('/register',
  validate(userValidation.register),
  async (req, res) => {
    // Data is already validated
    const { name, email, password, age } = req.body;
    
    const user = await User.create({ name, email, password, age });
    res.status(201).json({ success: true, data: user });
  }
);

router.post('/login',
  validate(userValidation.login),
  async (req, res) => {
    const { email, password } = req.body;
    // Login logic...
  }
);

router.get('/users/:id',
  validate(userValidation.id),
  async (req, res) => {
    const user = await User.findById(req.params.id);
    res.json(user);
  }
);

6. XSS Protection – Cross-Site Scripting

XSS (Cross-Site Scripting) attackers को malicious scripts inject करने देता है।

Prevention Methods:

Code
// 1. Escape output (EJS example)
// views/profile.ejs
// ❌ Dangerous – user input directly in HTML
<div><%= userInput %></div>

// ✅ Escape HTML
<div><%= escapeHtml(userInput) %></div>

// 2. Use helmet for XSS headers
app.use(helmet.xssFilter());

// 3. Content Security Policy
app.use(helmet.contentSecurityPolicy({
  directives: {
    scriptSrc: ["'self'"],
    defaultSrc: ["'self'"]
  }
}));

// 4. Sanitize user input
const DOMPurify = require('isomorphic-dompurify');

const sanitizeHtml = (html) => {
  return DOMPurify.sanitize(html);
};

app.post('/api/comments', (req, res) => {
  const cleanComment = sanitizeHtml(req.body.comment);
  // Save cleanComment to database
});

XSS Prevention Middleware:

Code
// middleware/xss.js
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');

const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

const xssProtection = (req, res, next) => {
  // Sanitize all string fields in body
  if (req.body) {
    for (let key in req.body) {
      if (typeof req.body[key] === 'string') {
        req.body[key] = DOMPurify.sanitize(req.body[key]);
      }
    }
  }
  
  // Sanitize query parameters
  if (req.query) {
    for (let key in req.query) {
      if (typeof req.query[key] === 'string') {
        req.query[key] = DOMPurify.sanitize(req.query[key]);
      }
    }
  }
  
  next();
};

module.exports = xssProtection;

7. CSRF Protection – Cross-Site Request Forgery

CSRF attackers को user की अनजानी में requests भेजने देता है।

Installation:

Code
npm install csurf

Basic CSRF Protection:

Code
const csrf = require('csurf');
const cookieParser = require('cookie-parser');

app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));

// CSRF protection middleware
const csrfProtection = csrf({ cookie: true });

// Routes
app.get('/form', csrfProtection, (req, res) => {
  // Send form with CSRF token
  res.send(`
    <form action="/submit" method="POST">
      <input type="hidden" name="_csrf" value="${req.csrfToken()}">
      <input type="text" name="data">
      <button type="submit">Submit</button>
    </form>
  `);
});

app.post('/submit', csrfProtection, (req, res) => {
  // Valid CSRF token required
  res.send('Data submitted!');
});

CSRF with Sessions:

Code
const session = require('express-session');
const csrf = require('csurf');

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: true,
  cookie: { secure: process.env.NODE_ENV === 'production' }
}));

const csrfProtection = csrf();

app.get('/api/csrf-token', csrfProtection, (req, res) => {
  res.json({ csrfToken: req.csrfToken() });
});

app.post('/api/sensitive-action', csrfProtection, (req, res) => {
  // Action requires valid CSRF token
  res.json({ message: 'Action completed' });
});

CSRF Token in Headers (for AJAX):

Code
// Frontend (JavaScript)
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

fetch('/api/sensitive-action', {
  method: 'POST',
  headers: {
    'CSRF-Token': csrfToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ data: 'value' })
});

8. SQL Injection Prevention

SQL Injection attackers को malicious SQL queries run करने देता है।

Prevention Methods:

Code
// ❌ DANGEROUS – SQL Injection vulnerable
const userId = req.params.id;
const query = `SELECT * FROM users WHERE id = ${userId}`;
db.query(query); // User can send: 1; DROP TABLE users; --

// ✅ SAFE – Parameterized queries (MySQL)
const userId = req.params.id;
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);

// ✅ SAFE – Parameterized queries (PostgreSQL)
const userId = req.params.id;
const query = 'SELECT * FROM users WHERE id = $1';
db.query(query, [userId]);

// ✅ SAFE – Mongoose (MongoDB)
const userId = req.params.id;
const user = await User.findById(userId); // Automatically sanitized

// ✅ SAFE – Prisma (Type-safe)
const userId = req.params.id;
const user = await prisma.user.findUnique({ where: { id: userId } });

Input Validation for SQL:

Code
// middleware/sqlInjection.js
const sqlInjectionPattern = /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER|CREATE|TRUNCATE|EXEC|EXECUTE)\b)|(--|;|'|\|\||\/\*|\*\/)/i;

const preventSqlInjection = (req, res, next) => {
  const checkValue = (value) => {
    if (typeof value === 'string' && sqlInjectionPattern.test(value)) {
      throw new Error('Potential SQL injection detected');
    }
    return value;
  };
  
  try {
    if (req.body) {
      for (let key in req.body) {
        req.body[key] = checkValue(req.body[key]);
      }
    }
    if (req.query) {
      for (let key in req.query) {
        req.query[key] = checkValue(req.query[key]);
      }
    }
    if (req.params) {
      for (let key in req.params) {
        req.params[key] = checkValue(req.params[key]);
      }
    }
    next();
  } catch (error) {
    res.status(400).json({ error: 'Invalid input detected' });
  }
};

module.exports = preventSqlInjection;

9. Other Security Headers

Additional Security Headers:

Code
// server.js
const express = require('express');
const app = express();

// 1. Remove X-Powered-By header
app.disable('x-powered-by');

// 2. Custom security headers
app.use((req, res, next) => {
  // Prevent MIME type sniffing
  res.setHeader('X-Content-Type-Options', 'nosniff');
  
  // Prevent clickjacking
  res.setHeader('X-Frame-Options', 'DENY');
  
  // Enable XSS filter
  res.setHeader('X-XSS-Protection', '1; mode=block');
  
  // Referrer policy
  res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
  
  // Permissions policy
  res.setHeader('Permissions-Policy', 
    'geolocation=(), microphone=(), camera=()'
  );
  
  // Cross-Origin policies
  res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
  res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
  res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
  
  next();
});

// 3. Trust proxy (if behind reverse proxy)
app.set('trust proxy', 1);

10. Production Security Checklist

Complete Security Checklist:

Code
// config/security.js
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const hpp = require('hpp');
const xss = require('xss-clean');
const compression = require('compression');

const securityConfig = (app) => {
  // 1. Helmet for security headers
  app.use(helmet());
  
  // 2. CORS configuration
  app.use(cors({
    origin: process.env.CORS_ORIGIN,
    credentials: true,
    optionsSuccessStatus: 200
  }));
  
  // 3. Rate limiting
  const limiter = rateLimit({
    windowMs: 15 * 60 * 1000,
    max: 100,
    message: 'Too many requests, please try again later.'
  });
  app.use('/api', limiter);
  
  // Stricter limiter for auth
  const authLimiter = rateLimit({
    windowMs: 15 * 60 * 1000,
    max: 5,
    message: 'Too many login attempts'
  });
  app.use('/api/auth', authLimiter);
  
  // 4. Body parser with size limit
  app.use(express.json({ limit: '10kb' }));
  app.use(express.urlencoded({ extended: true, limit: '10kb' }));
  
  // 5. Data sanitization against NoSQL injection
  app.use(mongoSanitize());
  
  // 6. Data sanitization against XSS
  app.use(xss());
  
  // 7. Prevent parameter pollution
  app.use(hpp());
  
  // 8. Compression
  app.use(compression());
  
  // 9. Remove X-Powered-By
  app.disable('x-powered-by');
  
  // 10. Cookie security
  app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: process.env.NODE_ENV === 'production',
      httpOnly: true,
      sameSite: 'strict',
      maxAge: 24 * 60 * 60 * 1000 // 24 hours
    }
  }));
  
  // 11. Trust proxy (for production)
  if (process.env.NODE_ENV === 'production') {
    app.set('trust proxy', 1);
  }
};

module.exports = securityConfig;

11. Complete Secure Server Setup

Production-Ready Secure Server:

Code
// server.js
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const xss = require('xss-clean');
const hpp = require('hpp');
const compression = require('compression');
const cookieParser = require('cookie-parser');

const app = express();

// ============ SECURITY MIDDLEWARE ============

// 1. Helmet (security headers)
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
    },
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  }
}));

// 2. CORS
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'];
app.use(cors({
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
  optionsSuccessStatus: 200
}));

// 3. Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  message: 'Too many requests, please try again later.',
  standardHeaders: true,
  legacyHeaders: false
});
app.use('/api', limiter);

const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: 'Too many login attempts, please try again later.',
  skipSuccessfulRequests: true
});
app.use('/api/auth', authLimiter);

// 4. Body parsers with size limit
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ extended: true, limit: '10kb' }));
app.use(cookieParser());

// 5. Data sanitization
app.use(mongoSanitize()); // NoSQL injection protection
app.use(xss()); // XSS protection
app.use(hpp()); // HTTP parameter pollution protection

// 6. Compression
app.use(compression());

// 7. Remove X-Powered-By
app.disable('x-powered-by');

// ============ DATABASE ============
mongoose.connect(process.env.MONGODB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

// ============ ROUTES ============
app.use('/api/auth', require('./routes/auth'));
app.use('/api/users', require('./routes/users'));
app.use('/api/products', require('./routes/products'));

// ============ ERROR HANDLING ============
app.use('*', (req, res) => {
  res.status(404).json({ error: `Cannot ${req.method} ${req.originalUrl}` });
});

// Global error handler
app.use((err, req, res, next) => {
  console.error(err);
  
  // Mongoose duplicate key error
  if (err.code === 11000) {
    return res.status(409).json({ error: 'Duplicate field value' });
  }
  
  // Mongoose validation error
  if (err.name === 'ValidationError') {
    return res.status(400).json({ error: err.message });
  }
  
  // JWT errors
  if (err.name === 'JsonWebTokenError') {
    return res.status(401).json({ error: 'Invalid token' });
  }
  
  if (err.name === 'TokenExpiredError') {
    return res.status(401).json({ error: 'Token expired' });
  }
  
  res.status(err.status || 500).json({
    error: process.env.NODE_ENV === 'production' 
      ? 'Internal server error' 
      : err.message
  });
});

// ============ START SERVER ============
const PORT = process.env.PORT || 3000;
const server = app.listen(PORT, () => {
  console.log(`🚀 Server running on port ${PORT}`);
  console.log(`🔒 Environment: ${process.env.NODE_ENV}`);
});

// Graceful shutdown
process.on('SIGTERM', () => {
  console.log('SIGTERM received, closing server...');
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});

module.exports = app;

12. Common Mistakes + Solutions

Mistake 1: CORS too permissive

Code
// ❌ Allows any domain
app.use(cors());

// ✅ Restrict to specific domains
app.use(cors({
  origin: 'https://myapp.com'
}));

Mistake 2: No rate limiting

Code
// ❌ No protection against brute force
app.post('/api/login', loginHandler);

// ✅ Add rate limiting
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5 });
app.post('/api/login', limiter, loginHandler);

Mistake 3: No input validation

Code
// ❌ Direct database query
app.post('/api/users', (req, res) => {
  db.query(`INSERT INTO users SET ?`, req.body);
});

// ✅ Validate input
app.post('/api/users', validateUser, (req, res) => {
  // Safe to use req.body
});

Mistake 4: Exposing stack traces

Code
// ❌ Shows stack trace in production
app.use((err, req, res, next) => {
  res.status(500).json({ error: err.stack });
});

// ✅ Hide stack traces in production
app.use((err, req, res, next) => {
  res.status(500).json({ 
    error: process.env.NODE_ENV === 'production' 
      ? 'Internal server error' 
      : err.message 
  });
});

13. Quick Cheat Sheet

Security Middleware Installation:

Code
npm install helmet cors express-rate-limit express-validator express-mongo-sanitize xss-clean hpp compression

Basic Security Setup:

Code
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');

app.use(helmet());
app.use(cors({ origin: 'https://yourdomain.com' }));
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
app.use(express.json({ limit: '10kb' }));
app.disable('x-powered-by');

Security Headers Reference:

HeaderPurpose
X-Frame-Options: DENYPrevent clickjacking
X-Content-Type-Options: nosniffPrevent MIME sniffing
X-XSS-Protection: 1; mode=blockXSS protection
Strict-Transport-SecurityEnforce HTTPS
Content-Security-PolicyResource whitelist
Referrer-PolicyControl referrer info

14. FAQ

Q1: Express security Helmet CORS rate limiting validation Hindi में सबसे important kya hai?
Helmet + Rate Limiting + Input Validation – ye three security layers sabse important हैं।

Q2: Helmet kya karta hai?
11+ security headers automatically set करता है – XSS, clickjacking, MIME sniffing etc. se bachata है।

Q3: CORS kyun chahiye?
Browser security policy – apne domain ke alawa kisi aur domain ko API access nahi देना चाहते तो CORS configure करो।

Q4: Rate limiting kyun important hai?
Brute force attacks, DDoS, abuse se बचाता है। Login attempts limit करना बहुत जरूरी है।

Q5: Input validation kyun chahiye?
SQL Injection, XSS attacks से बचाने के लिए। User input kabhi trust mat करो।

Q6: XSS attack kya hai?
Attacker malicious script inject करता है जो user के browser mein execute होती है।

Q7: CSRF attack kya hai?
Attacker user की unaware mein request भेजता है (जैसे money transfer)।

Q8: Production mein CORS origin kya set karein?
Sirf apne frontend domain(s) allow करो – * mat use करो।

Q9: Rate limit value kitni rakhein?
Public APIs – 100 per 15 minutes, Login – 5 per 15 minutes, Admin – 1000 per hour।

Q10: Security headers kaise check karein?
Browser DevTools → Network tab → Response headers देखो। Securityheaders.com tool use करो।

15. Conclusion

बहुत बढ़िया दोस्तों! आज हमने Express security Helmet CORS rate limiting validation Hindi को पूरी detail में समझा।

Quick Recap:

Security LayerProtection
HelmetSecurity headers
CORSCross-origin access
Rate LimitingBrute force / DDoS
Input ValidationSQL Injection, XSS
XSS ProtectionScript injection
CSRF ProtectionUnauthorized requests

Mera personal experience:

Pehle main security ko ignore karta था – “hackers mere chhote app ko target nahi karenge” – ye galat soch थी। एक बार app hacked हुआ तब सीखा। अब हर project mein ye security middleware compulsory हैं।

Tum bhi ye steps follow karo:

  1. ✅ Helmet install करो
  2. ✅ CORS configure करो (specific origins)
  3. ✅ Rate limiting add करो
  4. ✅ Input validation implement करो
  5. ✅ Security headers check करो

अब तुम्हारी बारी है!

नीचे comment में बताओ:

  1. तुमने कौन सा security measure pehle implement kiya?
  2. क्या तुम्हारा app production में secure है?
  3. अगला topic क्या चाहिए? (MongoDB Security? JWT Security? Docker Security?)

The Easy Master पर बने रहो। Happy Secure Coding! 🔐🚀

  • Express File Upload – Multer Se Image/PDF Kaise Upload Karein 2026
  • Express.js Mein Environment Variables – .env File Kaise Use Karein
  • Express Router – API Routes Ko Organize Karein (Modular Code)

Resources

Additional Resources

TheEasyMaster

Author at The Easy Master.

Related posts

Leave a Reply

Your email address will not be published. Required fields are marked *