0

Through reading the WebAuthn spec and related MDN docs, I understand that unlike "certificate signing requests", FIDO/Passkey can have various different attestation formats and verification methods/algorithms during public-key credential registeration.

The documents recommend against "profiling" authenticators. I find that to support all those different and potentially more attestation formats to be very complex.

If I only send the public key (obtained through the convenience API of AuthenticatorAttestationResponse.getPublicKey()) to the server, then ask the user to sign-in to prove their posession of private key through CredentialsContainer.get() interface, what protection do I lose in terms of security?

1 Answer 1

1

The server (but not the client) absolutely must receive, and validate, multiple parts of the AuthenticatorAttestationResponse beyond just the public key. Failure to do this would reduce the phishing and MitM protection that FIDO2/Webauthn is designed to provide. In particular, the server needs to verify that the challenge it sent to the client was correctly combined with the expected relaying party ID (the site domain, or other app ID) and credential ID, and that the resulting verificationData was correctly signed to produce the attestation signature (attStmt.sig from the decoded AuthenticatorAttestationResponse.attestationObject) using the credential's private key (meaning, you must validate the signature against the reconstructed verification data using the provided public key).

This means the server needs to know not only the public key, but also the attestation signature (part of the attStmt) and the data necessary to reconstruct the signed message: the authData, combined with values the server knows already (the challenge it issued, and the expected relaying party ID). The former fields are part of the decoded AuthenticatorAttestationResponse.attestationObject. The latter fields can be extracted from the AuthenticatorResponse.clientDataJSON if you want to validate that the authenticator did the expected thing, but this is not generally needed or recommended in the spec. (Obviously, you must not blindly trust them to be correct since they are supplied by the client; either validate them or ignore them and just use your known values for those fields!) As such, you need to send the attestationObject to the server, but I believe you don't necessarily need to send the clientDataJSON.

Simply sending the public key could allow for attacks such as using CSRF to associate an attacker's authenticator (and its public key) with your account (normally prevented by validating the challenge) and then logging in as you using their own authenticator's public key, or registering the user's actual public key but on a phishing site such that in the future the user can log in to their account via the phishing site and give the site access to their account (fixed by validating the relaying party ID). Both of those validations are part of the signature verification that requires all this data.

The server might have additional uses for the authenticator data, such as retrieving the name and type of authenticator (e.g. to display an icon along with the name for the user's assistance in identifying which or their authenticators it is, or to restrict allowed authenticator vendors). However, the critical security check is the signature validation. This is just as when logging in, where most of the same data is present and a very similar signature verification must be carried out by the server.


As a side note, I'm pretty sure webauthn libraries have now been written for all major web frameworks, and while the quality and completeness of those libraries will inevitably vary, I expect you can find one for any given format you want to use, and probably one that will handle (and abstract the differences between) multiple formats. As such, you shouldn't need to write your own implementation, and I recommend against doing so unless all the options are not only too flawed to use, but also to fork and fix, or work with the vendor on. Cryptography, even when you're just implementing a well-specified protocol using standard primitives, is complex and error-prone, and nearly everybody is better off using a library that hopefully has seen some external review, rather than trying to build their own implementation.

4
  • Some problems I'm seeing: (1) verificationData is only used in "FIDO U2F Attestation Statement Format". (2) Registeration is a sort of "trust-on-first-use" thing, so if an account is registered with a public key, CSRF cannot associate a different public key with the account without a 2nd factor. (3) even if an attacker manage to register "user's actual public key" on a phishing site, the client/authenticator won't produce a signature that can be verified with that public key, because that phishing site's "origin" is different, so a different key pair is used. Can you explain?
    – DannyNiu
    Feb 28 at 4:15
  • I've found this section from the WebAuthn spec (I specifically used an older version in case of link rot). Can you make refutation?
    – DannyNiu
    Feb 28 at 4:51
  • Most of this is true only for authentication signatures. The attestation signature is not even made with the credential private key, but with the authenticator vendor's attestation key (unless it's a self attestation, but that's mostly useless anyway). The value of the attestation signature is to prove the make and model of the authenticator; if you (the server) are not interested in that, you do not need to verify the attestation signature. In fact WebAuthn issue #1710 tracks an initiative to make attestation verification more clearly optional. Feb 28 at 20:35
  • 1
    Also, you do always need to send clientDataJSON to the server to verify both an attestation signature (which is not always relevant) and an authentication signature (which you absolutely always must, as outlined in the answer). The client may add properties to the clientDataJSON that the server does not know, so the server cannot reliably reconstruct clientDataJSON on its own. But you do need to validate in particular that the challenge and origin properties have the correct values. Feb 28 at 20:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .