Skip to content

Logging in with passkeys bypasses maximum session restriction #16685

@ziqin

Description

@ziqin

Describe the bug

In a Spring-built website with maximum session restriction, a user logging in with a passkey can bypass the maximum session restriction.

The above phenomenon is observed in Spring Security 6.4.3.

To Reproduce

  1. Use spring initializr to generate a new Spring project with “Spring Web” and “Spring Security” dependencies. Then manually add the webauthn4j-core dependency.
  2. Configure a SecurityFilterChain with WebAuthnConfigurer and SessionManagementConfigurer, setting maximumSession(1). Then, run the project.
  3. Visit http://localhost:8080/webauthn/register in a non-private browser window, sign in as user with username + password, and register a passkey.
  4. Visit http://localhost:8080/ in an “InPrivate” mode window, sign in as user with the registered passkey.
  5. Go back to the non-private window and refresh the authenticated page, we can observe that the user is not signed out by Spring Security.

Expected behavior

After the user started the second session in Step 4, he/she should be signed out when going back to the first session to refresh an authenticated page in Step 5.

Sample

The code of interest is listed below.

@SpringBootApplication
public class WebauthnSessionApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebauthnSessionApplication.class, args);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .sessionManagement(session -> session
                        .maximumSessions(1)
                        .expiredUrl("/login?logout"))
                .formLogin(Customizer.withDefaults())
                .webAuthn(webAuthn -> webAuthn
                        .rpId("localhost")
                        .rpName("Demo")
                        .allowedOrigins("http://localhost:8080"))
                .authorizeHttpRequests(authz -> authz
                        .anyRequest().authenticated());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build());
    }
}

A runnable project is uploaded as webauthn-session.tar.gz.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions