From 18f43b9d14ba2f7a4ab8df058a8bbf0ce051873e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Dubigny?= Date: Fri, 1 Dec 2023 19:15:47 +0100 Subject: [PATCH 1/2] feat: csrf is generated once per user session instead of once per request to avoid false positive csrf errors --- src/managers/session.ts | 1 + src/middlewares/csrf-protection.ts | 39 ++++++------------------------ 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/src/managers/session.ts b/src/managers/session.ts index 357f57aaf..a488d38a7 100644 --- a/src/managers/session.ts +++ b/src/managers/session.ts @@ -12,6 +12,7 @@ export const createLoggedInSession = async ( ): Promise => { // we store old session value to pass it to the new logged-in session // email will not be passed to the new session as it is not useful within logged session + // csrfToken should not be passed to the new session for security reasons const { interactionId, mustReturnOneOrganizationInPayload, diff --git a/src/middlewares/csrf-protection.ts b/src/middlewares/csrf-protection.ts index 9bcbb5f99..7114c1f97 100644 --- a/src/middlewares/csrf-protection.ts +++ b/src/middlewares/csrf-protection.ts @@ -1,36 +1,13 @@ import { csrfSync } from 'csrf-sync'; -import { NextFunction, Request, Response } from 'express'; -import * as Sentry from '@sentry/node'; +import { Request } from 'express'; -const { generateToken, invalidCsrfTokenError, isRequestValid, revokeToken } = - csrfSync({ - getTokenFromRequest: (req: Request) => { - return req.body['_csrf']; - }, - }); +const { generateToken, csrfSynchronisedProtection } = csrfSync({ + getTokenFromRequest: (req: Request) => { + return req.body['_csrf']; + }, +}); -export const csrfProtectionMiddleware = ( - req: Request, - res: Response, - next: NextFunction -) => { - const ignoredMethods = ['GET', 'HEAD', 'OPTIONS']; - const ignoredMethodsSet = new Set(ignoredMethods); - if (ignoredMethodsSet.has(req.method)) { - return next(); - } - - const isCsrfValid = isRequestValid(req); - // Csrf token cannot be re-used - revokeToken(req); - if (!isCsrfValid) { - const err = invalidCsrfTokenError; - Sentry.captureException(err); - return next(err); - } - - next(); -}; +export const csrfProtectionMiddleware = csrfSynchronisedProtection; // Csrf tokens are new for each requests -export const csrfToken = (req: Request) => generateToken(req, true); +export const csrfToken = (req: Request) => generateToken(req); From b0831c9a4e2dfdb649dc683d75bcb241be6d7d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Dubigny?= Date: Fri, 1 Dec 2023 19:16:09 +0100 Subject: [PATCH 2/2] feat: remove unused param --- src/views/user/unable-to-auto-join-organization.ejs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/views/user/unable-to-auto-join-organization.ejs b/src/views/user/unable-to-auto-join-organization.ejs index bbb21cb1e..bd32c9063 100644 --- a/src/views/user/unable-to-auto-join-organization.ejs +++ b/src/views/user/unable-to-auto-join-organization.ejs @@ -8,12 +8,7 @@

- ⏱️ Notre équipe est en train de vous rattacher à - <% if (locals.libelle) { %> - l’organisation <%= libelle %>. - <% } else { %> - cette organisation. - <% } %> + ⏱️ Notre équipe est en train de vous rattacher à cette organisation.

Vous recevrez un email pour accéder à votre démarche dès que nous aurons terminé.