fix(security): prevent admin token length leak via timing side-channel

isAdminMetricsAuthorized() returned early when buffer lengths differed,
allowing an attacker to discover the token length by measuring response
time. Now always calls crypto.timingSafeEqual (using a zeroed dummy
buffer on length mismatch) so every auth attempt takes constant time
regardless of whether the length guess was correct.

Reported-by: Kaia-Alenia
This commit is contained in:
KoalaDev
2026-06-16 04:21:15 +02:00
parent 7571f1986d
commit cc97e0d371
+7 -2
View File
@@ -33,8 +33,13 @@ export function isAdminMetricsAuthorized(authHeader, adminToken) {
const expectedBuffer = Buffer.from(adminToken);
const providedBuffer = Buffer.from(provided);
if (expectedBuffer.length !== providedBuffer.length) return false;
return crypto.timingSafeEqual(expectedBuffer, providedBuffer);
// Always run timingSafeEqual to prevent length-based timing leaks.
// timingSafeEqual throws on different-length buffers, so when lengths
// differ we compare against a zeroed buffer of the provided length
// (guaranteed mismatch, constant time).
const sameLength = expectedBuffer.length === providedBuffer.length;
const compareBuf = sameLength ? expectedBuffer : Buffer.alloc(providedBuffer.length);
return sameLength && crypto.timingSafeEqual(compareBuf, providedBuffer);
}
export function isAdminMetricsTokenStrong(adminToken, minLength = 32) {