• 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

    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

    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 CredentialRepository interface or the UsernameRepository interface may be affected. 
    • 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:

    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:

    1. 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.username or .userHandle in RelyingParty.startAssertion(StartAssertionOptions) or RelyingPartyV2.startAssertion(StartAssertionOptions). Both methods copy these values into their AssertionRequest output, which the application later passes as the FinishAssertionOptions.request input to RelyingParty.finishAssertion(FinishAssertionOptions) or RelyingPartyV2.finishAssertion(FinishAssertionOptions). Note that it is also possible, though not recommended, to construct FinishAssertionOptions manually without calling startAssertion.
    2. 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.username and .userHandle undefined in startAssertion and later also in finishAssertion.

    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, 2026GitHub user philsmart reported an error handling issue
    April 28, 2026Yubico validates issue report and identifies security impact
    May 12, 2026Yubico releases advisory YSA-2026-02