mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
fix(auth): guard the webauthn login challenge kind and require user verification
Mirror the TOTP login path: both the security-key verify and verify-options routes now reject any challenge whose kind is not "login" with the same generic 401, so a future step-up or non-login challenge can never mint a login session through these endpoints. Set the registration and authentication ceremonies to userVerification:"required" to match the server's UV enforcement — a key that passes the browser but skips UV would otherwise fail server-side.
This commit is contained in:
1 parent
51b8db166d
commit
2c1151dd40
3 files changed
+24
-4
No files matched your search
@@ -54,6 +54,13 @@ export const POST = apiHandler(async (request: NextRequest) => {
|
||||
return apiError("Invalid or expired challenge", 401);
|
||||
}
|
||||
|
||||
// Only a login-issued challenge may begin a login assertion here. Reject any
|
||||
// other challenge kind with the same generic 401.
|
||||
if (challenge.kind !== "login") {
|
||||
annotate({ action: { name: "auth.mfa.verify.invalid_ticket" } });
|
||||
return apiError("Invalid or expired challenge", 401);
|
||||
}
|
||||
|
||||
const result = await createMfaAuthenticationOptions(challenge.userId);
|
||||
if (!result) {
|
||||
// No registered security key for this account — the client should fall
|
||||
|
||||
@@ -69,6 +69,14 @@ export const POST = apiHandler(async (request: NextRequest) => {
|
||||
return apiError("Invalid or expired challenge", 401);
|
||||
}
|
||||
|
||||
// Only a login-issued challenge may be redeemed for a session here. A future
|
||||
// step-up or non-login challenge kind must never mint a login session through
|
||||
// this endpoint, so reject anything but "login" with the same generic 401.
|
||||
if (challenge.kind !== "login") {
|
||||
annotate({ action: { name: "auth.mfa.verify.invalid_ticket" } });
|
||||
return apiError("Invalid or expired challenge", 401);
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: challenge.userId },
|
||||
select: { id: true, username: true, onboardingCompletedAt: true },
|
||||
|
||||
Reference in new issue
Block a user