fix(webauthn): re-serialize the credential after an assertion

Persist the updated PublicKeyCredentialSource (not just the sign_count column)
so the next assertion validates against the latest counter — keeping the
library's cloned-authenticator / counter-rollback detection effective.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat/v1-foundation
boban 2026-06-14 18:33:20 +02:00
parent fe5c190eb0
commit 5704d6c0f7
1 changed files with 12 additions and 1 deletions

View File

@ -143,7 +143,18 @@ class WebauthnService
$validator = AuthenticatorAssertionResponseValidator::create($this->ceremony()->requestCeremony());
$updated = $validator->check($source, $assertion, $options, $this->rpId(), (string) $user->id);
$model->update(['sign_count' => $updated->counter, 'last_used_at' => now()]);
// Re-serialize the UPDATED record so the new sign counter is also embedded in
// public_key — otherwise the next assertion would validate against the stale
// registration-time counter and clone/rollback detection would never fire.
$updatedSource = $updated instanceof PublicKeyCredentialSource
? $updated
: PublicKeyCredentialSource::fromCredentialRecord($updated);
$model->update([
'public_key' => $serializer->serialize($updatedSource, 'json'),
'sign_count' => $updated->counter,
'last_used_at' => now(),
]);
session()->forget('webauthn.login');
return true;