Security Advisory YSA-2026-02
Security Advisory YSA-2026-02 – webauthn-server-core User Impersonation
Published Date: 2026-05-12
Tracking IDs: YSA-2026-02
CVE: Pending
CVSS: 7.7
Summary
A security update is available for the Yubico open-source software project webauthn-server-core to resolve a user impersonation vulnerability. No Yubico hardware is affected. In specific implementations, an attacker that has an existing account with a relying party (RP) can authenticate as a target user if that target user does not have a registered WebAuthn credential. This issue is rated as a high severity.
Affected Software
- webauthn-server-core (GitHub project java-webauthn-server) versions:
- Production Versions
- 2.8.0 to 2.8.1
- Alpha and Release Candidate Versions
- 2.6.0-alpha2 to 2.6.0-alpha8
- 2.7.0-alpha1
- 2.8.0-alpha1 to 2.8.0-alpha3
- 2.8.0-RC1
- 2.9.0-alpha1
- Production Versions
Not Affected Products
- No Yubico hardware is affected. This issue does not affect any YubiKey Series, YubiKey FIPS Series, Security Key Series, YubiHSM, or YubiHSM FIPS devices.
- webauthn-server-core (GitHub project java-webauthn-server) versions:
- Production Versions
- 2.5.4 and earlier
- 2.6.0
- 2.7.0
- Alpha and Release Candidate Versions
- 2.6.0-alpha1
- 2.6.0-RC1
- 2.7.0-RC1 to 2.7.0-RC3
- Production Versions
How to Tell if You Are Affected
Organizations using webauthn-server-core within the affected version range for WebAuthn server-side operations are potentially impacted if the implementation meets all of the following criteria:
- using the “second factor” flow (e.g. not using the “passkey” flow)
- using usernames to identify users
- Applications that implement the
CredentialRepositoryinterface or theUsernameRepositoryinterface may be affected.
- Applications that implement the
- authentication can be attempted for usernames that lack a WebAuthn user handle in the credential repository.
For more details about the “second factor” flow compared to the “passkey” flow as well as specific examples, see Issue Details below.
Customer Actions
Yubico recommends that affected customers update to version 2.8.2 or 2.9.0 or later of webauthn-server-core to resolve this issue.
Customers may also want to evaluate additional mitigations listed below:
- If implementing the
CredentialRepositoryinterface: Ensure that the implementation ofCredentialRepository.getUserHandleForUsernamealways returns a unique, non-empty result for registered usernames. - If implementing the
UsernameRepositoryinterface: Ensure that the implementation ofUsernameRepository.getUserHandleForUsernamealways returns a unique, non-empty result for registered usernames. - Avoid calling
RelyingParty.finishAssertion(FinishAssertionOptions)orRelyingPartyV2.finishAssertion(FinishAssertionOptions)withFinishAssertionOptions.request.usernameset.- Consequently, also avoid calling
RelyingParty.startAssertion(StartAssertionOptions)orRelyingPartyV2.startAssertion(StartAssertionOptions)withStartAssertionOptions.usernameset, as these methods copy this username value into theAssertionRequestwhich the application is later expected to pass asFinishAssertionOptions.requestinfinishAssertion.
- Consequently, also avoid calling
Monitoring
Applications that implement CredentialRepository may review their logs for any mismatches between input StartAssertionOptions.username and output AssertionResult.username.
Applications that implement UsernameRepository may review their logs for any mismatches between input StartAssertionOptions.username and output AssertionResultV2.getCredential().getUserHandle().
Applications without sufficient log coverage may review activity of user accounts with no associated WebAuthn user handle.
Issue Details
The library supports two modes of authentication:
- The “second factor” flow, where the user has already been identified before the WebAuthn authentication. For example, if the user first entered a username and password and then performs WebAuthn authentication as a second step, or if the user was tentatively identified by a cookie or similar. In the library this is expressed by setting
StartAssertionOptions.usernameor.userHandleinRelyingParty.startAssertion(StartAssertionOptions)orRelyingPartyV2.startAssertion(StartAssertionOptions). Both methods copy these values into theirAssertionRequestoutput, which the application later passes as theFinishAssertionOptions.requestinput toRelyingParty.finishAssertion(FinishAssertionOptions)orRelyingPartyV2.finishAssertion(FinishAssertionOptions). Note that it is also possible, though not recommended, to construct FinishAssertionOptions manually without calling startAssertion. - The “passkey” flow, where identification and authentication are done simultaneously during the WebAuthn authentication – for example if the user clicked a “sign in with a passkey” button without first entering a username. In the library this is expressed by leaving both
StartAssertionOptions.usernameand.userHandleundefined instartAssertionand later also infinishAssertion.
In the “second factor” flow, user identifiers are both inputs and outputs of the library processing and need to be validated for consistency, while in the “passkey” flow, user identifiers are only outputs of the library processing. The issue affects the consistency validation in the “second factor” flow and thus affects only the “second factor” mode.
A logic error in FinishAssertionSteps.java fails to cross-check the verified credential handle against the requested username when a userHandle is not found for that username during the initial lookup. If an attacker provides a valid assertion for their own account while targeting a username without a handle, the library incorrectly materializes an AssertionResult for the target user. If an application uses its input StartAssertionOptions.username or the output AssertionResult.username alone to identify the authenticated user, this may lead to user impersonation.
In both cases below, the attacker must have a WebAuthn credential registered, the attacker must know the target user name to impersonate, and the target username must not have a user handle associated.
RelyingParty Class with CredentialRepository Interface Details
If the application constructs a RelyingParty instance using the .credentialRepository(CredentialRepository) method of the RelyingParty builder, then the builder constructs a RelyingParty instance using the provided implementation of the CredentialRepository interface, including in particular its CredentialRepository.getUserHandleForUsername method.
In RelyingParty.finishAssertion(FinishAssertionOptions), if FinishAssertionOptions.request.username is set to a username for which CredentialRepository.getUserHandleForUsername returns empty, and the response FinishAssertionOptions.response.userHandle is set, then finishAssertion may finish successfully with a credential for a user different from FinishAssertionOptions.request.username, while AssertionResult.username incorrectly copies FinishAssertionOptions.request.username instead of the authenticated user.
RelyingPartyV2 Class with CredentialRepositoryV2 and UsernameRepository Interfaces Details
If the application does not use either of the RelyingParty builder methods .credentialRepository(CredentialRepository) or .usernameRepository(UsernameRepository), then the library does not process usernames and cannot exhibit this vulnerability.
If the application constructs a RelyingParty instance using the .credentialRepositoryV2(CredentialRepositoryV2) method of the RelyingParty builder, then the builder constructs a RelyingPartyV2 instance and the application may optionally also use the .usernameRepository(UsernameRepository) builder method to provide an implementation of the UsernameRepository interface, including in particular its UsernameRepository.getUserHandleForUsername method.
In RelyingPartyV2.finishAssertion(FinishAssertionOptions), if FinishAssertionOptions.request.username is set to a username for which UsernameRepository.getUserHandleForUsername returns empty, and FinishAssertionOptions.response.userHandle is set, then finishAssertion may finish successfully with a credential for a user different from FinishAssertionOptions.request.username.
Severity
Yubico has rated this issue as High severity
Timeline
| January 23, 2026 | GitHub user philsmart reported an error handling issue |
| April 28, 2026 | Yubico validates issue report and identifies security impact |
| May 12, 2026 | Yubico releases advisory YSA-2026-02 |