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

Handle Fido2VerificationException during credential creation #3873

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

trmartin4
Copy link
Member

@trmartin4 trmartin4 commented Mar 4, 2024

Type of change

- [X] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other

Objective

In #3615 we handled the Fido2VerificationException when asserting a WebAuthn credential for 2FA.

In this PR, we address the MakeNewCredentialAsync methods similarly, as well as the MakeAssertionAsync when asserting a WebAuthn credential for login, which was missed in #3615 .

📓 We have https://bitwarden.atlassian.net/browse/PM-4172 in the backlog to consolidate the implementations, at which point we should consider an abstraction.

Code changes

  • AssertWebAuthnLoginCredentialCommand: Added try/catch around assertion that returns a BadRequestException instead of the unhandled exception returned previously. This will be handled on the client, as it is the pattern already established in the class for communicating assertion errors.
  • CreateWebAuthnLoginCredentialCommand: Added try/catch around attestation that returns false along with a log message. I did this instead of throwing a BadRequestException as this is the pattern already established in this command for handling invalid data. I added a log here as returning false gives no indication of the root cause.
  • UserService: Added try/catch around attestation that returns false along with a log message. I did this instead of throwing a BadRequestException as this is the pattern already established in this command for handling invalid data. I added a log here as returning false gives no indication of the root cause.

Before you submit

  • Please check for formatting errors (dotnet format --verify-no-changes) (required)
  • If making database changes - make sure you also update Entity Framework queries and/or migrations
  • Please add unit tests where it makes sense to do so (encouraged but not required)
  • If this change requires a documentation update - notify the documentation team
  • If this change has particular deployment requirements - notify the DevOps team

@trmartin4 trmartin4 changed the title Wrapped calls to MakeNewCredentialAsync in try/catch Handle Fido2VerificationException during credential creation Mar 4, 2024
@trmartin4 trmartin4 marked this pull request as ready for review March 4, 2024 23:37
@trmartin4 trmartin4 requested a review from a team as a code owner March 4, 2024 23:37
@trmartin4 trmartin4 requested a review from coroiu March 4, 2024 23:40
@trmartin4
Copy link
Member Author

@coroiu do you recall why the Assert... command handles validation issues by throwing a BadRequestException, whereas the Create... command returns false? Is it because we are already returning additional data in the assertion, and it was more flexible to throw the exceptions?

@trmartin4 trmartin4 marked this pull request as draft March 5, 2024 01:03
Comment on lines -49 to +59
var assertionVerificationResult = await _fido2.MakeAssertionAsync(
assertionResponse, options, credentialPublicKey, (uint)credential.Counter, callback);

Fido2NetLib.Objects.AssertionVerificationResult assertionVerificationResult = null;
try
{
assertionVerificationResult = await _fido2.MakeAssertionAsync(
assertionResponse, options, credentialPublicKey, (uint)credential.Counter, callback);
}
catch (Fido2VerificationException)
{
throw new BadRequestException("Unable to verify credential.");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did I write this?? I must've completely missed the fact that _fido2.MakeAssertionAsync can throw exceptions... Good catch!

issue: So one thing we need to be careful with here is that we don't allow credential and/or user enumeration. If we have unique exception messages here then the caller will be able to differentiate between

  • Invalid Credential -> Not found in database
  • Unable to verify credential -> Found in database, but invalid assertion

@coroiu
Copy link
Contributor

coroiu commented Mar 5, 2024

@coroiu do you recall why the Assert... command handles validation issues by throwing a BadRequestException, whereas the Create... command returns false? Is it because we are already returning additional data in the assertion, and it was more flexible to throw the exceptions?

Yeah, I didn't like returning null to signify a failure so I ended up throwing exceptions. I probably should've changed the Create command to also throw exceptions, just for consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants