Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verification Options do not Return Saved Transports for Credentials #16084

Closed
Jyosua opened this issue Nov 13, 2024 · 2 comments
Closed

Verification Options do not Return Saved Transports for Credentials #16084

Jyosua opened this issue Nov 13, 2024 · 2 comments
Assignees
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug
Milestone

Comments

@Jyosua
Copy link

Jyosua commented Nov 13, 2024

Describe the bug
The transports saved with the credential during the registration request are not returned in the transports property of same credential within the Verification Options response provided by /webauthn/authenticate/options.

Note that I'm using the RC version of Spring Security 6.4.0.

To Reproduce

  1. Add a Security Configuration using the following implementation:
@Configuration
class SecurityConfig {

    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http
            .webAuthn{ it
                    .rpName("Example")
                    .rpId("example.localhost")
                    .allowedOrigins("https://example.localhost")
            }
            .authorizeRequests { it
                    .anyRequest()
                    .permitAll()
            }
            .csrf { it.disable() }
            
        return http.build()
    }

    val userDetails = User.withDefaultPasswordEncoder()
		.username("user")
		.password("password")
		.roles("USER")
		.build()

    @Bean
    fun userDetailsService(): UserDetailsService {
    	return InMemoryUserDetailsManager(userDetails)
    }
}
  1. Register a credential like the example in the docs but with an internal transport. Chrome virtual authenticator can be used to do this fairly easily.
{
  "publicKey": {
    "credential": {
      "id": "dYF7EGnRFFIXkpXi9XU2wg",
      "rawId": "dYF7EGnRFFIXkpXi9XU2wg",
      "response": {
        "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViUy9GqwTRaMpzVDbXq1dyEAXVOxrou08k22ggRC45MKNhdAAAAALraVWanqkAfvZZFYZpVEg0AEHWBexBp0RRSF5KV4vV1NsKlAQIDJiABIVggQjmrekPGzyqtoKK9HPUH-8Z2FLpoqkklFpFPQVICQ3IiWCD6I9Jvmor685fOZOyGXqUd87tXfvJk8rxj9OhuZvUALA",
        "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiSl9RTi10SFJYRWVKYjlNcUNrWmFPLUdOVmlibXpGVGVWMk43Z0ptQUdrQSIsIm9yaWdpbiI6Imh0dHBzOi8vZXhhbXBsZS5sb2NhbGhvc3Q6ODQ0MyIsImNyb3NzT3JpZ2luIjpmYWxzZX0",
        "transports": [
          "internal"
        ]
      },
      "type": "public-key",
      "clientExtensionResults": {},
      "authenticatorAttachment": "platform"
    },
    "label": "1password"
  }
}
  1. POST to /webauthn/authenticate/options
  2. The resulting response will have the registered credential in the allowCredentials, but the transports array will be empty.

Expected behavior
The request would return the credential in the allowCredentials with the same transport as was registered.

@Jyosua Jyosua added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 13, 2024
@sjohnr sjohnr added the in: web An issue in web modules (web, webmvc) label Nov 13, 2024
@krnbr
Copy link

krnbr commented Nov 27, 2024

@rwinch

The function registerCredential in the file org.springframework.security.web.webauthn.management.Webauthn4JRelyingPartyOperations is not storing the secureTransports correctly

It should have been like below:-

presently it is like below

ImmutableCredentialRecord userCredential = ImmutableCredentialRecord.builder()
			.....
			.transports(convertTransports(registrationData.getTransports()))
			....
			.build();

instead of registrationData.getTransports() it should have been -

.transports(new HashSet<>(response.getTransports()))

Tried debugging the flow, registrationData.getTransports() comes blank/null

while response.getTransports() is getting populated with values.

@rwinch rwinch removed the status: waiting-for-triage An issue we've not yet triaged label Dec 4, 2024
@rwinch rwinch added this to the 6.4.2 milestone Dec 4, 2024
@rwinch rwinch closed this as completed in 9c3b119 Dec 4, 2024
@rwinch
Copy link
Member

rwinch commented Dec 4, 2024

Thanks for the report @Jyosua the fix is now merged into main.

@krnbr Thanks for the pointer. The underlying issue was that the transports weren't being passed to webauthn4j which meant they were null. By passing it to webauthn4j, the transports are now returned. Note that this is preferred because we want to ensure that it aligns with what the webauthn4j library has verified vs what is being passed in as (untrusted) input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug
Projects
Status: No status
Development

No branches or pull requests

4 participants