Merge remote-tracking branch 'origin/main' into refactor/codebase-cleanup
# Conflicts: # backend/src/routes/adminEvents.js # backend/src/routes/protectedImages.js # frontend/src/pages/admin/EventDetailsPage.tsx
This commit is contained in:
@@ -32,7 +32,7 @@ function hasValidAdminToken(req) {
|
||||
|
||||
// Critical: Verify token is valid before skipping rate limit
|
||||
// This prevents invalid tokens from bypassing rate limiting
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] });
|
||||
|
||||
// Additional validation
|
||||
if (!decoded || typeof decoded !== 'object') {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* Constant-time string comparison for secrets (share tokens, HMAC
|
||||
* signatures, etc.). Returns false for non-strings or length mismatch
|
||||
* without leaking timing beyond the (non-secret) length. Prevents an
|
||||
* attacker from recovering a token byte-by-byte via response-time
|
||||
* differences of a naive `a === b`.
|
||||
*/
|
||||
function timingSafeEqualStr(a, b) {
|
||||
if (typeof a !== 'string' || typeof b !== 'string') {
|
||||
return false;
|
||||
}
|
||||
const ab = Buffer.from(a);
|
||||
const bb = Buffer.from(b);
|
||||
if (ab.length !== bb.length) {
|
||||
return false;
|
||||
}
|
||||
return crypto.timingSafeEqual(ab, bb);
|
||||
}
|
||||
|
||||
module.exports = { timingSafeEqualStr };
|
||||
Reference in New Issue
Block a user