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
Implementing Caching in Express
Visit Our Quality Thought Training Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments