Add CSRF Middleware
Create a middleware to protect your app from Cross Site Request Forgery (CSRF) attacks.
When using the Backend Server Integration Pattern for your application, you must protect against CSRF attacks which can trick authenticated users into unknowingly submitting malicious requests.
Create CSRF Middleware
To prevent this, implement a CSRF middleware to protect your application. View our documentation for more details about this topic.
Prerequisite: Cookie Parsing
Skip This Part If Using Session Middleware
If you're using
iron-session
orexpress-session
for session management, you can skip installingcookie-parser
. These session libraries already include the necessary cookie handling for CSRF protection. Proceed to the next step below: "Install CSRF SDK".
CSRF protection requires access to cookies from incoming requests. Ensure that the cookie-parser middleware is installed for direct cookie access (req.cookies
):
npm install cookie-parser
yarn add cookie-parser
pnpm add cookie-parser
In your main Express application file, add the cookie-parser
middleware as early as possible in your middleware chain:
// app.ts
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
// Add the cookie-parser middleware.
app.use(cookieParser());
//
// Your other middleware and routes come after...
//
module.exports = app;
Install CSRF SDK
You can use the csrf library for implementing CSRF protection in Express.
npm install csrf
yarn add csrf
pnpm add csrf
Add CSRF Helper Functions
You'll need a couple functions for use in both a middleware you will create as well as in your Callback endpoint (e.g. src/utils/csrf.ts
).
// csrf.ts
import Tokens from 'csrf';
const csrfTokens = new Tokens();
// Updates the CSRF cookie with a new CSRF token.
export const updateCsrfTokenAndCookie = function (req, res) {
const csrfToken = csrfTokens.create(req.session.csrfSecret);
res.cookie('XSRF-TOKEN', csrfToken, {
httpOnly: false, // Must be false so that your frontend AJAX client can access the value.
maxAge: 1800000, // e.g. 30 minutes; Ideally, it should match your access token expiration.
path: '/',
sameSite: true, // May need to set this to 'Lax' if dealing with CORS in your environment
secure: false, // IMPORTANT: set to true for production environments!!
});
};
// Generates new CSRF tokens.
export const createCsrfSecret = function () {
return csrfTokens.secretSync();
};
// Verifies that the CSRF token in the request header was cryptographically generated from the
// CSRF secret in your application session.
export const isCsrfTokenValid = function (req) {
const csrfToken = req.headers['x-xsrf-token'];
if (!csrfToken || !req.session.csrfSecret){
return false;
}
return csrfTokens.verify(req.session.csrfSecret, csrfToken);
};
Implement Middleware
Create a new file for a CSRF middleware (eg. src/middleware/csrf-middleware.ts
).
// csrf-middleware.ts
import { isCsrfTokenValid, updateCsrfTokenAndCookie } from '@/utils/csrf';
const csrfMiddleware = function (req, res, next) {
if (!isCsrfTokenValid(req)) {
return res.status(403).send();
}
// After validation, a new CSRF token is generated and set into the CSRF response cookie.
updateCsrfTokenAndCookie(req, res);
return next();
};
Protect the Session Route
You will need to apply the CSRF middleware to any protected routes that also require an authenticated user session to access. Here's how to protect the Session endpoint:
// app.ts
import { authMiddleware, csrfMiddleware } from './middleware';
...
// Session endpoint, now with both auth and CSRF middlewares
app.get('/session', [authMiddleware, csrfMiddleware], (req, res) => {
const { email, isAuthenticated } = req.session;
return res.status(200).json({ isAuthenticated, email });
});
...
Put All Protected Routes Behind Middleware
Protect all authenticated routes - not just the Session endpoint - with the CSRF middleware. Add this middleware to any endpoint that requires an authenticated user session.
The Login, Callback, and Logout Express routes are meant to be accessed by unauthenticated users. Avoid sticking the CSRF middleware in front of those routes.
Updated 19 days ago
Next, let's enhance the auth routes to add CSRF management logic.