chore: clean up CSRF implementation
- Remove unused generateCsrfToken export from security.ts - Remove redundant /csrf-token path check (GET already exempt) - Restore defineConfig wrapper in vitest.config.ts for type safety
This commit is contained in:
Generated
+6
@@ -1128,6 +1128,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
|
||||||
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
|
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.16.0"
|
"undici-types": "~7.16.0"
|
||||||
}
|
}
|
||||||
@@ -3813,6 +3814,7 @@
|
|||||||
"integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==",
|
"integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/engines": "5.22.0"
|
"@prisma/engines": "5.22.0"
|
||||||
},
|
},
|
||||||
@@ -4819,6 +4821,7 @@
|
|||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -4977,6 +4980,7 @@
|
|||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -5054,6 +5058,7 @@
|
|||||||
"integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
|
"integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.5.0",
|
"fdir": "^6.5.0",
|
||||||
@@ -5147,6 +5152,7 @@
|
|||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,16 +381,12 @@ const csrfProtectionMiddleware = (
|
|||||||
next: express.NextFunction
|
next: express.NextFunction
|
||||||
) => {
|
) => {
|
||||||
// Skip CSRF validation for safe methods (GET, HEAD, OPTIONS)
|
// 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"];
|
const safeMethods = ["GET", "HEAD", "OPTIONS"];
|
||||||
if (safeMethods.includes(req.method)) {
|
if (safeMethods.includes(req.method)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip CSRF for the CSRF token endpoint itself
|
|
||||||
if (req.path === "/csrf-token") {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Origin/Referer check for defense in depth
|
// Origin/Referer check for defense in depth
|
||||||
const origin = req.headers["origin"];
|
const origin = req.headers["origin"];
|
||||||
const referer = req.headers["referer"];
|
const referer = req.headers["referer"];
|
||||||
|
|||||||
@@ -605,14 +605,7 @@ const signCsrfToken = (clientId: string, payload: CsrfTokenPayload): Buffer => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a cryptographically secure CSRF token
|
* Create a new CSRF token for a client
|
||||||
*/
|
|
||||||
export const generateCsrfToken = (): string => {
|
|
||||||
return crypto.randomBytes(CSRF_TOKEN_LENGTH).toString("hex");
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and store a new CSRF token for a client
|
|
||||||
* Returns the token to be sent to the client
|
* Returns the token to be sent to the client
|
||||||
*/
|
*/
|
||||||
export const createCsrfToken = (clientId: string): string => {
|
export const createCsrfToken = (clientId: string): string => {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { defineConfig } from "vitest/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
environment: "node",
|
environment: "node",
|
||||||
@@ -18,4 +20,4 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user