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
parent
fe5c190eb0
commit
5704d6c0f7
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue