arcanajs 6.1.0-beta.3 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2429,6 +2429,28 @@ function _interop_require_default(obj) {
|
|
|
2429
2429
|
};
|
|
2430
2430
|
}
|
|
2431
2431
|
const CSRF_COOKIE_NAME = "_csrf";
|
|
2432
|
+
/**
|
|
2433
|
+
* Timing-safe CSRF token comparison to prevent timing attacks
|
|
2434
|
+
* This ensures that token validation takes constant time regardless of where
|
|
2435
|
+
* the tokens differ, preventing attackers from using timing analysis to
|
|
2436
|
+
* guess valid tokens character by character.
|
|
2437
|
+
*/ function isValidCsrfToken(providedToken, expectedToken) {
|
|
2438
|
+
// Ensure both tokens are the same length to prevent timing attacks
|
|
2439
|
+
// If lengths differ, we still perform a comparison to maintain constant time
|
|
2440
|
+
if (providedToken.length !== expectedToken.length) {
|
|
2441
|
+
// Create a dummy token of the same length as expected for constant-time comparison
|
|
2442
|
+
const dummyToken = "0".repeat(expectedToken.length);
|
|
2443
|
+
_crypto.default.timingSafeEqual(Buffer.from(dummyToken), Buffer.from(expectedToken));
|
|
2444
|
+
return false;
|
|
2445
|
+
}
|
|
2446
|
+
try {
|
|
2447
|
+
// Perform constant-time comparison of the tokens
|
|
2448
|
+
return _crypto.default.timingSafeEqual(Buffer.from(providedToken), Buffer.from(expectedToken));
|
|
2449
|
+
} catch (error) {
|
|
2450
|
+
// If buffer conversion fails, tokens are invalid
|
|
2451
|
+
return false;
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2432
2454
|
const createCsrfMiddleware = ()=>{
|
|
2433
2455
|
return (req, res, next)=>{
|
|
2434
2456
|
// 1. Generate or retrieve token
|
|
@@ -2452,7 +2474,14 @@ const createCsrfMiddleware = ()=>{
|
|
|
2452
2474
|
"PATCH"
|
|
2453
2475
|
].includes(method)) {
|
|
2454
2476
|
const headerToken = req.headers["x-csrf-token"];
|
|
2455
|
-
|
|
2477
|
+
// Validate token exists and is a string
|
|
2478
|
+
if (!headerToken || typeof headerToken !== "string") {
|
|
2479
|
+
return res.status(403).json({
|
|
2480
|
+
error: "Invalid CSRF Token"
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
// Use timing-safe comparison to prevent timing attacks
|
|
2484
|
+
if (!isValidCsrfToken(headerToken, token)) {
|
|
2456
2485
|
return res.status(403).json({
|
|
2457
2486
|
error: "Invalid CSRF Token"
|
|
2458
2487
|
});
|