From 21ab20bba97102fe9eb9d4af4213a604c05e0acc Mon Sep 17 00:00:00 2001 From: fallenbagel <98979876+fallenbagel@users.noreply.github.com> Date: Tue, 11 Mar 2025 09:33:40 +0800 Subject: [PATCH] revert: reverts csrf-csrf back to csurf (#1442) * revert: reverts csrf-csrf back to csurf This reverts csrf-csrf change brought on by `9e3119` in #1393 back to `csurf` that is maintained * fix: type declarations for csurf --- package.json | 2 +- pnpm-lock.yaml | 49 ++++++++++++++++++++++++++++++-------- server/index.ts | 29 ++++++++++------------ server/types/custom.d.ts | 4 ++++ src/utils/fetchOverride.ts | 2 +- 5 files changed, 57 insertions(+), 29 deletions(-) create mode 100644 server/types/custom.d.ts diff --git a/package.json b/package.json index 830f9930f..67cbb55e5 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ }, "license": "MIT", "dependencies": { + "@dr.pogodin/csurf": "^1.14.1", "@formatjs/intl-displaynames": "6.2.6", "@formatjs/intl-locale": "3.1.1", "@formatjs/intl-pluralrules": "5.1.10", @@ -51,7 +52,6 @@ "copy-to-clipboard": "3.3.3", "country-flag-icons": "1.5.5", "cronstrue": "2.23.0", - "csrf-csrf": "^3.1.0", "date-fns": "2.29.3", "dayjs": "1.11.7", "email-templates": "12.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a14c07169..4f46a78dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@dr.pogodin/csurf': + specifier: ^1.14.1 + version: 1.14.1 '@formatjs/intl-displaynames': specifier: 6.2.6 version: 6.2.6 @@ -65,9 +68,6 @@ importers: cronstrue: specifier: 2.23.0 version: 2.23.0 - csrf-csrf: - specifier: ^3.1.0 - version: 3.1.0 date-fns: specifier: 2.29.3 version: 2.29.3 @@ -1549,6 +1549,10 @@ packages: '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + '@dr.pogodin/csurf@1.14.1': + resolution: {integrity: sha512-ijqJsKSDlepDYbprkEEcqbiYero2y4DeL4X5ivnkbKonliLtH8SfHCEtdUwoRZLPTUy2WeFPHI+gveU+Z8ZxLA==} + engines: {node: '>= 18'} + '@emnapi/runtime@1.2.0': resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} @@ -4405,6 +4409,10 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} @@ -4417,6 +4425,10 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} @@ -4509,9 +4521,6 @@ packages: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} - csrf-csrf@3.1.0: - resolution: {integrity: sha512-kZacFfFbdYFxNnFdigRHCzVAq019vJyUUtgPLjCtzh6jMXcWmf8bGUx/hsqtSEMXaNcPm8iXpjC+hW5aeOsRMg==} - css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -8317,6 +8326,9 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rndm@1.2.0: + resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==} + run-applescript@3.2.0: resolution: {integrity: sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==} engines: {node: '>=4'} @@ -9064,6 +9076,10 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + tsutils@3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -11290,6 +11306,15 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 + '@dr.pogodin/csurf@1.14.1': + dependencies: + cookie: 1.0.2 + cookie-signature: 1.2.2 + http-errors: 2.0.0 + rndm: 1.2.0 + tsscmp: 1.0.6 + uid-safe: 2.1.5 + '@emnapi/runtime@1.2.0': dependencies: tslib: 2.6.3 @@ -14928,12 +14953,16 @@ snapshots: cookie-signature@1.0.6: {} + cookie-signature@1.2.2: {} + cookie@0.4.2: {} cookie@0.7.1: {} cookie@0.7.2: {} + cookie@1.0.2: {} + copy-to-clipboard@3.3.3: dependencies: toggle-selection: 1.0.6 @@ -15044,10 +15073,6 @@ snapshots: crypto-random-string@2.0.0: {} - csrf-csrf@3.1.0: - dependencies: - http-errors: 2.0.0 - css-select@4.3.0: dependencies: boolbase: 1.0.0 @@ -19665,6 +19690,8 @@ snapshots: dependencies: glob: 7.2.3 + rndm@1.2.0: {} + run-applescript@3.2.0: dependencies: execa: 0.10.0 @@ -20534,6 +20561,8 @@ snapshots: tslib@2.8.1: {} + tsscmp@1.0.6: {} + tsutils@3.21.0(typescript@4.9.5): dependencies: tslib: 1.14.1 diff --git a/server/index.ts b/server/index.ts index d672f6229..d8aadfa0a 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1,3 +1,4 @@ +import csurf from '@dr.pogodin/csurf'; import PlexAPI from '@server/api/plexapi'; import dataSource, { getRepository, isPgsql } from '@server/datasource'; import DiscoverSlider from '@server/entity/DiscoverSlider'; @@ -28,7 +29,6 @@ import restartFlag from '@server/utils/restartFlag'; import { getClientIp } from '@supercharge/request-ip'; import { TypeormStore } from 'connect-typeorm/out'; import cookieParser from 'cookie-parser'; -import { doubleCsrf } from 'csrf-csrf'; import type { NextFunction, Request, Response } from 'express'; import express from 'express'; import * as OpenApiValidator from 'express-openapi-validator'; @@ -162,23 +162,18 @@ app } }); if (settings.network.csrfProtection) { - const { doubleCsrfProtection, generateToken } = doubleCsrf({ - getSecret: () => settings.clientId, - cookieName: 'XSRF-TOKEN', - cookieOptions: { - httpOnly: true, - sameSite: 'strict', - secure: !dev, - }, - size: 64, - ignoredMethods: ['GET', 'HEAD', 'OPTIONS'], - }); - - server.use(doubleCsrfProtection); - + server.use( + csurf({ + cookie: { + httpOnly: true, + sameSite: true, + secure: !dev, + }, + }) + ); server.use((req, res, next) => { - res.cookie('XSRF-TOKEN', generateToken(req, res), { - sameSite: 'strict', + res.cookie('XSRF-TOKEN', req.csrfToken(), { + sameSite: true, secure: !dev, }); next(); diff --git a/server/types/custom.d.ts b/server/types/custom.d.ts new file mode 100644 index 000000000..f2f47c60f --- /dev/null +++ b/server/types/custom.d.ts @@ -0,0 +1,4 @@ +declare module '@dr.pogodin/csurf' { + import csrf = require('csurf'); + export = csrf; +} diff --git a/src/utils/fetchOverride.ts b/src/utils/fetchOverride.ts index bd4dcd43b..e0a900125 100644 --- a/src/utils/fetchOverride.ts +++ b/src/utils/fetchOverride.ts @@ -31,7 +31,7 @@ if (typeof window !== 'undefined') { const headers = { ...(init?.headers || {}), - ...(csrfToken ? { 'X-CSRF-TOKEN': csrfToken } : {}), + ...(csrfToken ? { 'XSRF-TOKEN': csrfToken } : {}), }; const newInit: RequestInit = {