mirror of
https://github.com/open-reception/appointment-booking-software.git
synced 2026-09-08 02:07:39 +02:00
Extract Counter against replay attacks
This commit is contained in:
@@ -214,4 +214,28 @@ export class WebAuthnService {
|
||||
static async getUserPasskeys(userId: string) {
|
||||
return await centralDb.select().from(userPasskey).where(eq(userPasskey.userId, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract counter from WebAuthn credential response
|
||||
* Used during registration to get the initial counter value
|
||||
*/
|
||||
static extractCounterFromCredential(credential: {
|
||||
response: {
|
||||
authenticatorData: string;
|
||||
};
|
||||
}): number {
|
||||
try {
|
||||
// Parse authenticator data
|
||||
const authenticatorDataBuffer = Buffer.from(credential.response.authenticatorData, "base64");
|
||||
|
||||
// Extract counter from authenticator data (bytes 33-36)
|
||||
const counter = authenticatorDataBuffer.readUInt32BE(33);
|
||||
|
||||
logger.debug("Counter extracted from credential", { counter });
|
||||
return counter;
|
||||
} catch (error) {
|
||||
logger.error("Failed to extract counter from credential", { error: String(error) });
|
||||
return 0; // Fallback to 0 if extraction fails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { json } from "@sveltejs/kit";
|
||||
import { UserService } from "$lib/server/services/user-service";
|
||||
import { WebAuthnService } from "$lib/server/auth/webauthn-service";
|
||||
import { ValidationError } from "$lib/server/utils/errors";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import { registerOpenAPIRoute } from "$lib/server/openapi";
|
||||
@@ -154,10 +155,13 @@ export const POST: RequestHandler = async ({ request, cookies, url }) => {
|
||||
// Clear the registration cookie after validation (challenge cookie is cleared by login route)
|
||||
cookies.delete("webauthn-registration-email", { path: "/" });
|
||||
|
||||
// Extract counter from WebAuthn credential
|
||||
const counter = WebAuthnService.extractCounterFromCredential(body.passkey);
|
||||
|
||||
await UserService.addPasskey(admin.id, {
|
||||
id: body.passkey.id,
|
||||
publicKey: body.passkey.publicKey,
|
||||
counter: body.passkey.counter || 0,
|
||||
counter,
|
||||
deviceName: body.passkey.deviceName || "Unknown Device"
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { json } from "@sveltejs/kit";
|
||||
import { UserService } from "$lib/server/services/user-service";
|
||||
import { WebAuthnService } from "$lib/server/auth/webauthn-service";
|
||||
import { NotFoundError, ValidationError } from "$lib/server/utils/errors";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import { registerOpenAPIRoute } from "$lib/server/openapi";
|
||||
@@ -115,12 +116,15 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
deviceName: body.passkey.deviceName
|
||||
});
|
||||
|
||||
// Extract counter from WebAuthn credential
|
||||
const counter = WebAuthnService.extractCounterFromCredential(body.passkey);
|
||||
|
||||
// Add the passkey using the UserService
|
||||
await UserService.addAdditionalPasskey(body.userId, {
|
||||
id: body.passkey.id,
|
||||
userId: body.userId,
|
||||
publicKey: body.passkey.publicKey,
|
||||
counter: body.passkey.counter || 0,
|
||||
counter,
|
||||
deviceName: body.passkey.deviceName || "Unknown Device"
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { json } from "@sveltejs/kit";
|
||||
import { UserService } from "$lib/server/services/user-service";
|
||||
import { InviteService } from "$lib/server/services/invite-service";
|
||||
import { WebAuthnService } from "$lib/server/auth/webauthn-service";
|
||||
import { ValidationError } from "$lib/server/utils/errors";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import { registerOpenAPIRoute } from "$lib/server/openapi";
|
||||
@@ -201,10 +202,13 @@ export const POST: RequestHandler = async ({ request, cookies, url }) => {
|
||||
// Clear the registration cookie after validation (challenge cookie is cleared by login route)
|
||||
cookies.delete("webauthn-registration-email", { path: "/" });
|
||||
|
||||
// Extract counter from WebAuthn credential
|
||||
const counter = WebAuthnService.extractCounterFromCredential(body.passkey);
|
||||
|
||||
await UserService.addPasskey(user.id, {
|
||||
id: body.passkey.id,
|
||||
publicKey: body.passkey.publicKey,
|
||||
counter: body.passkey.counter || 0,
|
||||
counter,
|
||||
deviceName: body.passkey.deviceName || "Unknown Device"
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user