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 or express-session for session management, you can skip installing cookie-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.


Whatโ€™s Next

Next, let's enhance the auth routes to add CSRF management logic.