VYPR
Moderate severityNVD Advisory· Published Oct 16, 2023· Updated Sep 13, 2024

Improper signature counter value handling in webauthn4j-spring-security

CVE-2023-45669

Description

WebAuthn4J Spring Security provides Web Authentication specification support for Spring applications. Affected versions are subject to improper signature counter value handling. A flaw was found in webauthn4j-spring-security-core. When an authneticator returns an incremented signature counter value during authentication, webauthn4j-spring-security-core does not properly persist the value, which means cloned authenticator detection does not work. An attacker who cloned valid authenticator in some way can use the cloned authenticator without being detected. This issue has been addressed in version 0.9.1.RELEASE. Users are advised to upgrade. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
com.webauthn4j:webauthn4j-spring-security-coreMaven
< 0.9.1.RELEASE0.9.1.RELEASE

Affected products

1

Patches

1
129700d74d83

Merge pull request from GHSA-v9hx-v6vf-g36j

4 files changed · +18 11
  • gradle.properties+2 2 modified
    @@ -13,5 +13,5 @@
     # See the License for the specific language governing permissions and
     # limitations under the License.
     #
    -webAuthn4JSpringSecurityVersion=0.9.1-SNAPSHOT
    -latestReleasedWebAuthn4JSpringSecurityVersion=0.9.0.RELEASE
    +webAuthn4JSpringSecurityVersion=0.9.1.RELEASE
    +latestReleasedWebAuthn4JSpringSecurityVersion=0.9.1.RELEASE
    
  • README.md+1 1 modified
    @@ -24,7 +24,7 @@ If you are using Maven, just add the webauthn4j-spring-security as a dependency:
     <properties>
       ...
       <!-- Use the latest version whenever possible. -->
    -  <webauthn4j-spring-security.version>0.9.0.RELEASE</webauthn4j-spring-security.version>
    +  <webauthn4j-spring-security.version>0.9.1.RELEASE</webauthn4j-spring-security.version>
       ...
     </properties>
     
    
  • samples/spa/src/test/java/e2e/RegistrationAndAuthenticationE2ETest.java+14 1 modified
    @@ -16,6 +16,7 @@
     
     package e2e;
     
    +import com.webauthn4j.springframework.security.authenticator.WebAuthnAuthenticatorService;
     import com.webauthn4j.springframework.security.webauthn.sample.SampleSPA;
     import e2e.page.AuthenticatorLoginComponent;
     import e2e.page.PasswordLoginComponent;
    @@ -34,18 +35,24 @@
     import org.openqa.selenium.support.ui.WebDriverWait;
     import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
     import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;
    +import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.boot.test.context.SpringBootTest;
     import org.springframework.test.context.junit4.SpringRunner;
     
     import java.time.Duration;
     
    +import static org.assertj.core.api.Assertions.assertThat;
    +
     @RunWith(SpringRunner.class)
     @SpringBootTest(classes = SampleSPA.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
     public class RegistrationAndAuthenticationE2ETest {
     
         private WebDriver driver;
         private WebDriverWait wait;
     
    +    @Autowired
    +    private WebAuthnAuthenticatorService webAuthnAuthenticatorService;
    +
         @BeforeClass
         public static void setupClassTest() {
             WebDriverManager.chromedriver().setup();
    @@ -86,8 +93,10 @@ public void test() {
             signupComponent.waitRegisterClickable();
             signupComponent.clickRegister();
     
    -        // Password authentication
             wait.until(ExpectedConditions.urlToBe("http://localhost:8080/angular/login"));
    +        long counterValueAtRegistrationPhase = webAuthnAuthenticatorService.loadAuthenticatorsByUserPrincipal("john.doe@example.com").get(0).getCounter();
    +
    +        // Password authentication
             PasswordLoginComponent passwordLoginComponent = new PasswordLoginComponent(driver);
             passwordLoginComponent.setUsername("john.doe@example.com");
             passwordLoginComponent.setPassword("password");
    @@ -98,6 +107,10 @@ public void test() {
             // nop
     
             wait.until(ExpectedConditions.urlToBe("http://localhost:8080/angular/profile"));
    +        long counterValueAtAuthenticationPhase = webAuthnAuthenticatorService.loadAuthenticatorsByUserPrincipal("john.doe@example.com").get(0).getCounter();
    +
    +        assertThat(counterValueAtAuthenticationPhase).isGreaterThan(counterValueAtRegistrationPhase);
    +
             ProfileComponent profileComponent = new ProfileComponent(driver);
     
         }
    
  • webauthn4j-spring-security-core/src/main/java/com/webauthn4j/springframework/security/WebAuthnAuthenticationProvider.java+1 7 modified
    @@ -136,13 +136,7 @@ void doAuthenticate(WebAuthnAssertionAuthenticationToken authenticationToken, We
             );
             AuthenticationParameters authenticationParameters = new AuthenticationParameters(
                     parameters.getServerProperty(),
    -                new AuthenticatorImpl(
    -                        webAuthnAuthenticator.getAttestedCredentialData(),
    -                        webAuthnAuthenticator.getAttestationStatement(),
    -                        webAuthnAuthenticator.getCounter(),
    -                        webAuthnAuthenticator.getTransports(),
    -                        webAuthnAuthenticator.getClientExtensions(),
    -                        webAuthnAuthenticator.getAuthenticatorExtensions()),
    +                webAuthnAuthenticator,
                     null,
                     parameters.isUserVerificationRequired(),
                     parameters.isUserPresenceRequired()
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.