@@ -1,3 +1,5 @@
|
||||
import { timingSafeEqual } from "crypto";
|
||||
|
||||
import createMiddleware from "next-intl/middleware";
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
@@ -111,6 +113,20 @@ function isAdminBasicAuthConfigured(): boolean {
|
||||
return Boolean(getAdminBasicAuthUser() && getAdminBasicAuthPass());
|
||||
}
|
||||
|
||||
function timingSafeStringEqual(a: string, b: string): boolean {
|
||||
const left = Buffer.from(a);
|
||||
const right = Buffer.from(b);
|
||||
|
||||
// Buffers of different length must still be compared against something of
|
||||
// equal length so the comparison time doesn't leak the expected length.
|
||||
if (left.length !== right.length) {
|
||||
timingSafeEqual(left, left);
|
||||
return false;
|
||||
}
|
||||
|
||||
return timingSafeEqual(left, right);
|
||||
}
|
||||
|
||||
function isAdminBasicAuthValid(request: NextRequest): boolean {
|
||||
if (!isAdminBasicAuthConfigured()) {
|
||||
return false;
|
||||
@@ -131,7 +147,10 @@ function isAdminBasicAuthValid(request: NextRequest): boolean {
|
||||
const user = decoded.slice(0, index);
|
||||
const pass = decoded.slice(index + 1);
|
||||
|
||||
return user === getAdminBasicAuthUser() && pass === getAdminBasicAuthPass();
|
||||
const userValid = timingSafeStringEqual(user, getAdminBasicAuthUser());
|
||||
const passValid = timingSafeStringEqual(pass, getAdminBasicAuthPass());
|
||||
|
||||
return userValid && passValid;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user