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

Enforce backup eligibility during assertion #1791

Closed
Firstyear opened this issue Aug 30, 2022 · 8 comments
Closed

Enforce backup eligibility during assertion #1791

Firstyear opened this issue Aug 30, 2022 · 8 comments

Comments

@Firstyear
Copy link
Contributor

Proposed Change

https://github.com/w3c/webauthn/blob/main/index.bs#L983

Currently this text states:

:: A [=Public Key Credential Source=]'s [=generating authenticator=] determines at creation time whether the [=public key credential source=]
    is allowed to be [=backed up=]. Backup eligibility is signaled in [=authenticator data=]'s [=flags=] along with the current [=backup state=].
    Backup eligibility is a [=credential property=] and is permanent for a given [=public key credential source=].
    A backup eligible [=public key credential source=] is referred to as a <dfn>multi-device credential</dfn> whereas one that is not
    backup eligible is referred to as a <dfn>single-device credential</dfn>. See also [[#sctn-credential-backup]].

The detail here is that "Backup eligibility is a credential property and is permanent".

We can see during registration that this property is checked by:

https://github.com/w3c/webauthn/blob/main/index.bs#L5029

However during assertion the BE property is NOT checked.

This has now lead to Apple's iOS and macOS sending BE=true during registration, but BE=false during subsequent usage of the credential during assertion ceremonies. This is certainly 'an' interpretation of the above sections, but it is ambiguous to other potential readings of the text. For example, my interpretation is that a property being permanent means that the credential will always send BE=true during any ceremony, and that BE=true changing to BE=false is invalid because you can-not "un-backup" a credential.

The primary reason to harden this is that (I think?) Apple plan to upgrade credentials from being BE=false to BE=true, and due to their current design, this WONT be signalled to RP's meaning they miss the ability to make informed choices about this change in properties during assertion.

Additionally it is confusing to an RP today when at registration a permanent property is changing between registration and assertion.

So I think that some clarity is needed here that either:

  • That the BE flag is persisted by the RP during registration
  • That during assertion BE=true/false is consistent to the persisted BE state OR that the RP is allowed to make an informed decision if this value changes.

OR

  • The BE flag is registration only, and that it's "permanency" exists due to the RP persisting the BE flag allowing post-reg auditing.
  • That BE will ALWAYS be false in assertions and setting it to true is invalid. The only time you will be aware of a credential being BE=true is during registration.

Thoughts?

@emlun
Copy link
Member

emlun commented Aug 30, 2022

I agree that it's probably good to set an explicit standard for how RPs should react if BE changes, or if BE=0, BS=1, to encourage consistent behaviour between services.

I'm not sure what that should be, though. The user probably has little insight on, let alone control of, the flags, so rejecting the assertion or even revoking the credential seems unfair to the user. But if things don't break, there's little incentive for authenticator vendors to implement the flags correctly. But if things do break, there is incentive for RPs to ignore the recommendation to make their user experience more pleasant.

@timcappalli
Copy link
Member

This has now lead to Apple's iOS and macOS sending BE=true during registration, but BE=false during subsequent usage of the credential during assertion ceremonies.

This is likely a bug. I, personally, am not seeing this behavior on the latest betas.

Additionally it is confusing to an RP today when at registration a permanent property is changing between registration and assertion.

It cannot change after registration. We already have normative text about this: https://w3c.github.io/webauthn/#sctn-credential-backup

"The value of the BE flag is set during authenticatorMakeCredential operation and MUST NOT change."

@emlun
Copy link
Member

emlun commented Aug 30, 2022

It cannot change after registration. We already have normative text about this: [...]

Yes, but there is no guidance (normative or informative) on what RPs should do if they encounter the forbidden cases (BE=1 => 0 or BE=0, BS=1).

@agl
Copy link
Contributor

agl commented Aug 30, 2022

This has now lead to Apple's iOS and macOS sending BE=true during registration, but BE=false during subsequent usage of the credential during assertion ceremonies.

This is likely a bug. I, personally, am not seeing this behavior on the latest betas.

(BE/BS flags are part of my testing and I've not seen this in any Apple beta.)

@MasterKale
Copy link
Contributor

MasterKale commented Aug 30, 2022

Yes, but there is no guidance (normative or informative) on what RPs should do if they encounter the forbidden cases (BE=1 => 0 or BE=0, BS=1).

I do agree that an official decision should be made. Two insanely popular WebAuthn libraries currently reject registration and authentication based on the fact that be:0, bs:1 is "not allowed" because it is the opinion of the authors (read: me 😂) that this reflects an authenticator that is acting up, and that it is a problem that should be fixed at the authenticator level so that it becomes compliant with the spec.

Edit: That is to say that other libraries may decide it isn't so bad that 0/1 gets returned and not error out, leading to fragmented implementations of the spec across the ecosystem, without an official stance here in the spec.

@Firstyear
Copy link
Contributor Author

Firstyear commented Aug 31, 2022

Two insanely popular WebAuthn libraries currently reject registration and authentication based on the fact that be:0, bs:1 is "not allowed"

Are you counting webauthn-rs in that list? if not, that makes three libraries. :)

So reading these points, I think it sounds like we should have an explicit step in the spec stating that if BE changes during a credential lifecycle the RP can choose to reject or take other action then? I think it sounds like we are mostly in agreement that we should have better specification here.

@nadalin nadalin added this to the L3-WD-01 milestone Sep 7, 2022
@nadalin nadalin assigned MasterKale and unassigned emlun Sep 12, 2022
@MasterKale
Copy link
Contributor

MasterKale commented Apr 21, 2023

We can see during registration that this property is checked by:

https://github.com/w3c/webauthn/blob/main/index.bs#L5029

However during assertion the BE property is NOT checked.

@Firstyear The content of the spec has shifted since this issue was initially created. Can you track down where (perhaps in the rendered version of L3 https://w3c.github.io/webauthn/) you were pointing to about be not being checked during the assertion? Was it in the processing steps here?

https://w3c.github.io/webauthn/#sctn-discover-from-external-source

@Firstyear
Copy link
Contributor Author

It's here:

https://w3c.github.io/webauthn/#backup-eligibility

"""
A Public Key Credential Source's generating authenticator determines at creation time whether the public key credential source is allowed to be backed up. Backup eligibility is signaled in authenticator data's flags along with the current backup state. Backup eligibility is a credential property and is permanent for a given public key credential source. A backup eligible public key credential source is referred to as a multi-device credential whereas one that is not backup eligible is referred to as a single-device credential. See also § 6.1.3 Credential Backup State.
"""

As we can see the text is the same, and indicates that BE is a creation only property, and is also permanent for the life of the credential. This means that if BE is only sent at credential create and later changes then implementations may not signal it to RP's.

As a result, my view is that BE/BS are properties that should be sent both during creation (attestation) and authentication (assertion) so that if a vendor changes their BE state then RP's are able to see this during the life of a credential because these states are not permanent - they are actually dynamic and changing on some implementations.

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

No branches or pull requests

6 participants