Friday, November 28, 2025

thumbnail

Preventing XSS & CSRF in MERN

 Preventing XSS & CSRF in MERN


Modern MERN applications must defend against two common web vulnerabilities:


XSS (Cross-Site Scripting) – injecting malicious scripts into web pages.


CSRF (Cross-Site Request Forgery) – tricking users into performing unwanted actions.


Below are best practices to protect your MERN application from both.


๐Ÿ” 1. Preventing XSS (Cross-Site Scripting)


XSS happens when untrusted user input gets executed as JavaScript in the browser.


1. Escape & Sanitize User Input

Backend (Node/Express)


Use trusted validation + sanitization libraries:


express-validator


validator.js


DOMPurify (server version)


Example:


const { body } = require("express-validator");


app.post("/comment",

  body("text").trim().escape(), 

  (req, res) => {

    // safe text

});


Frontend (React)


React automatically escapes values in JSX:


<p>{userInput}</p>



This prevents HTML/script injection by default.


⚠️ Never use dangerouslySetInnerHTML unless absolutely required.

If you do, sanitize with DOMPurify:


import DOMPurify from 'dompurify';


<div

  dangerouslySetInnerHTML={{

    __html: DOMPurify.sanitize(userHtml),

  }}

></div>


2. Use Helmet in Express


Helmet sets important security headers:


import helmet from "helmet";

app.use(helmet());



It adds defenses like:


X-XSS-Protection


Content-Security-Policy (CSP)


X-Content-Type-Options


3. Implement a Strong Content Security Policy (CSP)


CSP prevents inline scripts and unauthorized sources from running.


app.use(

  helmet.contentSecurityPolicy({

    directives: {

      defaultSrc: ["'self'"],

      scriptSrc: ["'self'"],

      objectSrc: ["'none'"],

      styleSrc: ["'self'", "'unsafe-inline'"],

    },

  })

);



This dramatically reduces XSS impact.


4. Prevent NoSQL Injection (MongoDB)


XSS can combine with NoSQL injection (e.g., malicious JSON).


Use:


mongoose schema validation


express-validator


mongo-sanitize


import sanitize from 'mongo-sanitize';

const cleanData = sanitize(req.body);


๐Ÿ›ก 2. Preventing CSRF (Cross-Site Request Forgery)


CSRF forces authenticated users to perform actions they didn’t intend.


1. Avoid Storing JWT Tokens in Cookies


Storing JWT in:


localStorage → XSS risk


HTTP-only cookies → CSRF risk


Best practice for MERN:


Store JWT in memory (React state or Redux)


Refresh tokens in HTTP-only cookie with CSRF protection


2. Use CSRF Protection Middleware


If you use cookies for authentication, add csurf in Express:


import csurf from "csurf";

const csrfProtection = csurf({ cookie: true });


app.use(csrfProtection);



Then send the token to the frontend:


app.get("/api/csrf-token", (req, res) => {

  res.json({ csrfToken: req.csrfToken() });

});



React sends the CSRF token with each request.


3. SameSite Cookies


Set SameSite to prevent cross-site submission:


res.cookie("token", jwt, {

  httpOnly: true,

  secure: true,

  sameSite: "strict",

});



Options:


"strict" – best security, but can break some cross-site flows


"lax" – good balance


"none" – only with secure: true (for HTTPS only)


4. Use Double-Submit Cookie Pattern


Frontend sends:


The CSRF token in a header.


Cookie contains the same token.


Server checks if they match.


Example:


axios.post("/update", data, {

  headers: {

    'X-CSRF-Token': csrfToken

  }

});


5. Use Referrer and Origin Validation


Add middleware to block suspicious cross-site requests:


app.use((req, res, next) => {

  const origin = req.get("origin");

  if (origin && origin !== process.env.ALLOWED_ORIGIN) {

    return res.status(403).send("Forbidden");

  }

  next();

});


6. Use Access Tokens Only for APIs


API requests from React → include Bearer token:


Authorization: Bearer <token>



CSRF works only on cookies.

Bearer tokens are immune to CSRF when not stored in cookies.


Summary Table

Threat Mitigation

XSS Sanitization, React escaping, DOMPurify, CSP, Helmet

Stored/Reflected XSS Validate input, sanitize output

DOM-Based XSS Avoid dangerouslySetInnerHTML

CSRF csurf, SameSite cookies, token validation

CSRF with JWT Use Authorization header, not cookies

Injection attacks Mongoose schemas, mongo-sanitize

✅ Final Summary


To secure your MERN application:


Against XSS


Sanitize data (server + client)


Avoid dangerous HTML injection


Use Helmet + CSP


Validate data and escape output


Against CSRF


Use Bearer tokens, not cookies (if possible)


Add csurf protection when using cookies


Use SameSite cookies


Validate origins and CSRF tokens

Learn 

MERN Stack Training in Hyderabad

Read More

Securing Your MERN Stack App

Optimizing MongoDB Queries

Load Testing Node.js APIs

Implementing Caching in Express

Visit Our Quality Thought Training Institute in Hyderabad

Get Directions 


Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive