mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-05 23:00:10 +00:00
fix:Harden authentication and sensitive file handling
This commit is contained in:
+16
-7
@@ -70,17 +70,22 @@ function normalizeToken(token: string): string {
|
||||
return token.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
export async function verifyTotpToken(secretRaw: string, tokenRaw: string, nowMs: number = Date.now()): Promise<boolean> {
|
||||
export async function findMatchingTotpCounter(
|
||||
secretRaw: string,
|
||||
tokenRaw: string,
|
||||
nowMs: number = Date.now()
|
||||
): Promise<number | null> {
|
||||
const token = normalizeToken(tokenRaw);
|
||||
if (!/^\d{6}$/.test(token)) return false;
|
||||
if (!/^\d{6}$/.test(token)) return null;
|
||||
|
||||
const secret = base32Decode(secretRaw);
|
||||
if (!secret) return false;
|
||||
if (!secret) return null;
|
||||
|
||||
const currentCounter = Math.floor(nowMs / 1000 / TOTP_STEP_SECONDS);
|
||||
let matched = false;
|
||||
let matchedCounter: number | null = null;
|
||||
for (let delta = -TOTP_WINDOW; delta <= TOTP_WINDOW; delta++) {
|
||||
const expected = await hotp(secret, currentCounter + delta);
|
||||
const candidateCounter = currentCounter + delta;
|
||||
const expected = await hotp(secret, candidateCounter);
|
||||
// Constant-time comparison: always check all windows, never short-circuit.
|
||||
const a = new TextEncoder().encode(expected);
|
||||
const b = new TextEncoder().encode(token);
|
||||
@@ -88,9 +93,13 @@ export async function verifyTotpToken(secretRaw: string, tokenRaw: string, nowMs
|
||||
for (let i = 0; i < a.length && i < b.length; i++) {
|
||||
diff |= a[i] ^ b[i];
|
||||
}
|
||||
if (diff === 0) matched = true;
|
||||
if (diff === 0 && matchedCounter == null) matchedCounter = candidateCounter;
|
||||
}
|
||||
return matched;
|
||||
return matchedCounter;
|
||||
}
|
||||
|
||||
export async function verifyTotpToken(secretRaw: string, tokenRaw: string, nowMs: number = Date.now()): Promise<boolean> {
|
||||
return (await findMatchingTotpCounter(secretRaw, tokenRaw, nowMs)) != null;
|
||||
}
|
||||
|
||||
export function isTotpEnabled(secretRaw: string | undefined | null): boolean {
|
||||
|
||||
Reference in New Issue
Block a user