diff --git a/backend/package-lock.json b/backend/package-lock.json index 9735739..10b57c8 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1128,6 +1128,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -3813,6 +3814,7 @@ "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@prisma/engines": "5.22.0" }, @@ -4819,6 +4821,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4977,6 +4980,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5054,6 +5058,7 @@ "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -5147,6 +5152,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, diff --git a/backend/src/index.ts b/backend/src/index.ts index b354846..5e2025f 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -381,16 +381,12 @@ const csrfProtectionMiddleware = ( next: express.NextFunction ) => { // Skip CSRF validation for safe methods (GET, HEAD, OPTIONS) + // Note: /csrf-token is a GET endpoint, so it's automatically exempt const safeMethods = ["GET", "HEAD", "OPTIONS"]; if (safeMethods.includes(req.method)) { return next(); } - // Skip CSRF for the CSRF token endpoint itself - if (req.path === "/csrf-token") { - return next(); - } - // Origin/Referer check for defense in depth const origin = req.headers["origin"]; const referer = req.headers["referer"]; diff --git a/backend/src/security.ts b/backend/src/security.ts index e1dfb50..ef724c4 100644 --- a/backend/src/security.ts +++ b/backend/src/security.ts @@ -605,14 +605,7 @@ const signCsrfToken = (clientId: string, payload: CsrfTokenPayload): Buffer => { }; /** - * Generate a cryptographically secure CSRF token - */ -export const generateCsrfToken = (): string => { - return crypto.randomBytes(CSRF_TOKEN_LENGTH).toString("hex"); -}; - -/** - * Create and store a new CSRF token for a client + * Create a new CSRF token for a client * Returns the token to be sent to the client */ export const createCsrfToken = (clientId: string): string => { diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index 082b7c5..18be842 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -1,4 +1,6 @@ -export default { +import { defineConfig } from "vitest/config"; + +export default defineConfig({ test: { globals: true, environment: "node", @@ -18,4 +20,4 @@ export default { }, }, }, -}; +});