mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
fix(recovery): check a pasted token key against its slow fingerprint
The kit's check compared keyed SHA-256 digests of the pasted value and the configured key, which code scanning still reads as a fast hash of a password. It now compares the scrypt fingerprints in constant time.
This commit is contained in:
1 parent
3939c9c0a5
commit
78de978dcd
1 file changed
+5
-8
@@ -3,7 +3,7 @@
|
||||
* stored confirmation covers, recording a confirmation, and "Check my copy".
|
||||
* The rules themselves are pure and live in `kit-rules.ts`.
|
||||
*/
|
||||
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
||||
import { timingSafeEqual } from "node:crypto";
|
||||
|
||||
import { prisma } from "@/lib/db";
|
||||
import { envValue } from "@/lib/env";
|
||||
@@ -29,9 +29,7 @@ import {
|
||||
type KitKeyKind,
|
||||
type RecoveryKit,
|
||||
} from "@/lib/recovery/kit-rules";
|
||||
|
||||
/** Keys the constant-time comparison below; never leaves the process. */
|
||||
const COMPARE_KEY = randomBytes(32);
|
||||
import { fingerprintSecretText } from "@/lib/database-backup/dump-core.mjs";
|
||||
|
||||
/** Every key the kit lists on this server right now, without a verdict. */
|
||||
export async function listKitKeys(
|
||||
@@ -168,11 +166,10 @@ export function verifyKitKey(input: {
|
||||
case "token": {
|
||||
const configured = envValue("API_TOKEN_HMAC_KEY");
|
||||
if (!configured || input.id !== KIT_KEY_SOURCES.token) return false;
|
||||
// Keyed digests under a key of this process, so the comparison is
|
||||
// constant time whatever the lengths and nothing derived from the
|
||||
// secret outlives the call.
|
||||
// The slow fingerprint the kit shows, compared in constant time: equal
|
||||
// lengths whatever was pasted, and no fast digest of the secret.
|
||||
const digest = (s: string) =>
|
||||
createHmac("sha256", COMPARE_KEY).update(s).digest();
|
||||
Buffer.from(fingerprintSecretText(s), "utf8");
|
||||
return timingSafeEqual(digest(value), digest(configured));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user