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

Backup state of credentials #1692

Closed
akshayku opened this issue Jan 25, 2022 · 15 comments · Fixed by #1695
Closed

Backup state of credentials #1692

akshayku opened this issue Jan 25, 2022 · 15 comments · Fixed by #1695

Comments

@akshayku
Copy link
Contributor

akshayku commented Jan 25, 2022

With recent multi-device passkeys concept for backup and recovery purposes and the desire to remove passwords from the account, we need to provide signal to the RP that it can go ahead and remove passwords.

This is a refinement of original proposal of "durable" flags in https://github.com/w3c/webauthn/wiki/Explainer:-broadening-the-user-base-of-WebAuthn#durable-signal
(which is derived from: #1637 (comment))

dpk, as per current definition in the WebAuthn PR #1663 is that it is just another key which is device bound. It does not tell whether primary credential is device bound or not.

Windows current thinking is that if and when we implement multi-device backup, user will be given a choice of whether they want these credentials to be backed-up or not at registration time. User may also have ability to choose sync/backup state in the future depending on various factors like access to sync/backup fabric etc. and it's properties. Which means that backup state of the credential can change over time. And RP should be able to determine what is happening from the authenticator responses.

There are two possible solution around this.

  1. Extension: "backup-state"

    • The extension tells RP about the backup state the credential.
    • Need

      • Existing devices which does not support backup and newer devices which may support backup needs to coexist.
      • RP also needs to distinguish between device bound key vs non-device bound key in certain situations.
      • RP needs to know in which state the credential is in so that it can offer removal of password from the account.
      • User will be offered choice on certain platforms and authenticators where user may transition from unbacked-up state to backup-state or vice-versa.
      • Hence the value is dynamic in nature if backup is supported by the authenticator.
    • Applicability

      • Both at credential.create() as well credential.get()
    • Values

      • BACKUP_NOT_APPLICABLE
        • Credential created is device bound and does not support backup now or in future.
        • All existing credentials created are in this state.
        • Device-public-key extension is not returned in this state.
        • Default state if extension is not returned
      • BACKUP_NOT_CONFIGURED
        • Credential is not configured to be backed-up at this time but may be configured in future.
        • Device-public-key extension should be returned in this state.
      • BACKUP_IN_PROGRESS
        • Device-public-key extension should be returned in this state.
        • Typically in credential.create() stage where credential has just been created and not yet synced but should be synced shortly.
      • BACKUP_COMPLETED
        • Device-public-key extension should be returned in this state.
  2. Authenticator Flags (as proposed by @ve7jtb)

    • Single Device 0 / multi-device capable 1
    • Not backed up 0 / backed up 1

cc @agl / @equalsJeffH / @timcappalli

@agl
Copy link
Contributor

agl commented Jan 25, 2022

Looks good to me, either encoded in an extension, or using two of the three bits of flags.

@ve7jtb
Copy link
Contributor

ve7jtb commented Jan 25, 2022

I prefer to use two of the bit flags, that will allow for the response information to be unsolicited.
It also prevents any tampering with the request that would be required for an extension.

@emlun
Copy link
Member

emlun commented Jan 25, 2022

Haven't we already changed so extensions may now be unsolicited, motivated by credProps? In L2 we have this in §7.1. Registering a New Credential:

Note: Client platforms MAY enact local policy that sets additional authenticator extensions or client extensions and thus cause values to appear in the authenticator extension outputs or client extension outputs that were not originally specified as part of options.extensions. Relying Parties MUST be prepared to handle such situations, whether it be to ignore the unsolicited extensions or reject the attestation. The Relying Party can make this decision based on local policy and the extensions in use.

But I agree the flags should be tamper-protected, so either authenticator flags or an authenticator extension.

@akshayku
Copy link
Contributor Author

akshayku commented Jan 26, 2022

It also prevents any tampering with the request that would be required for an extension.

If we choose extension route, then platforms and authenticators have to support it. RP may or may not need to change the request depending upon whether we can include the extension by default in user-agent/platform and whether they care. But this is not called tampering the request. It is called supporting a new extension. :)

It seems like flags may be simpler. Need some more time to think on this.

@ve7jtb
Copy link
Contributor

ve7jtb commented Jan 26, 2022

We changed level 2 to allow unsolicited.
That is not to say that there won't be a pile of existing RP's with code that might be based on Level 1 that might reject assertions with unknown extensions.

Flags are less likely to break existing RP and don't require additional bits to be sent in both the request and response that an extension would.

I could live with it as an extension but think using the bit flags is cleaner.

@equalsJeffH
Copy link
Contributor

I think bit flags are a cleaner approach overall, for reasons @ve7jtb expresses.

@nadalin nadalin added this to the L3-WD-01 milestone Jan 26, 2022
@dwaite
Copy link
Contributor

dwaite commented Jan 27, 2022

We changed level 2 to allow unsolicited.
That is not to say that there won't be a pile of existing RP's with code that might be based on Level 1 that might reject assertions with unknown extensions.

AFAIK are already long-broken via the (relatively popular) combination of authenticators which support credProtect and browsers which mandate its use if available.

I would be more inclined to reserve these bits for mandatory-to-understand extensions as well as changes to the structure of authenticator data.

Bits are also very hard to change the meaning of once (beta) implementations have shipped or to otherwise semantically version. A backupState extension can change structure or even be replaced with an extension with a new name.

@sbweeden
Copy link
Contributor

credProps is a client extension only.

@dwaite
Copy link
Contributor

dwaite commented Jan 27, 2022

credProps is a client extension only.

oops - changed to credProtect

@rlin1
Copy link
Contributor

rlin1 commented Feb 17, 2022

Some additional considerations:

  1. Security related and
  2. adoption related

1. Security Related:
Both, extensions and the authenticator flags are signed by the key in question (that could potentially be backed-up and restored to a different authenticator instance - potentially with different security (e.g. key protection) characteristics.

Following scenario:
a) key/credential being generated in a very secure authenticator (e.g. secure element level key protection). Registration assertion truthfully reports multi-device capable, not backed up.
b) first authentication happens and authentication assertion truthfully reports multi-device capable, not backed up.
c) second authentication happens and authentication assertion truthfully reports multi-device capable, backed-up (now backup was performed)
d) key is being restored in a much less secure authenticator (e.g. rich-OS SW level) and key was extracted by an attacker.
e) attacker performs authentication and authentication assertion maliciously reports "not backed up" (and potentially even "single device". Since the attacker has access to private key in the clear, any extension/authenticator flags could be generated and signed.

Note that in reality step b+c could even be omitted, making it more complex for the RP to determine the risk.

For me it means that (from a security perspective), it is important
(i) to have the option to request attestation and to have a description in the related MetadataStatement whether this authenticator supports multi-device keys in general or not and
(ii) that the trust that an RP might have in the flags included in the registration assertion (i.e. attestation statement) would be "higher" than the trust in the extensions/flags in the authentication assertion (if the authenticator supports multi-device credentials). - Because of (d) + (e).
(iii) to emphasize that seeing "single device" in an authentication assertion after having seen "multi-device/capable") in any assertion is an indication of increased risk (potential attack).
(iv) the flag backed-up or not-backed-up is relevant for driving user experience (but very limited from a security perspective), i.e. don't think the key is more secure just because you haven't seen a "backed-up" indication in any assertion yet.

2. Adoption Related
The way we have architected extensions, requires FIDO Clients (e.g. Browsers) to actively "pass them through". Additional flags in the assertion on the other hand would be "passed through" by default. That means that the "flags" approach will work ubiquitously, while the extension approach might require changes (depending on the implementation approach in Browsers).

@dwaite
Copy link
Contributor

dwaite commented Feb 18, 2022

a) key/credential being generated in a very secure authenticator (e.g. secure element level key protection). Registration assertion truthfully reports multi-device capable, not backed up.

My feeling is that an authenticator is defined today effectively as "abstract thing that performs user presence and verification, and registers, asserts, and protects its public keys". There's nothing about the authenticator being a single device, being hardware or software, or whether it stores into a TPM-protected storage or into a GitHub gist.

The concept of a device is being added, and extensions are being added to give multi-device authenticators additional capabilities specifically because otherwise, relying party policies will reject their use.

An attestation continues to infer such implementation details to policy. How one receives access to private keys, via sync fabric of approved TPMs or a PIN-protected file or a CSV would be part of those details. The weakest security link drags everything down - if it is possible to recover into an arbitrary authenticator, that greatly decreases the trustworthiness of the original registered credential.

The device public key extension, sent on registration and on use, effectively allows one to make judgements both based on the details of the device and on the backup/restore mechanism.

e) attacker performs authentication and authentication assertion maliciously reports "not backed up" (and potentially even "single device". Since the attacker has access to private key in the clear, any extension/authenticator flags could be generated and signed.

If anything, it sounds like we need to make it clearer that these flags on their own do not imply some security policy is met, just as UP and UV on their own make no guarantee that the user is present or verified.

But in addition - the backed-up flag is not meant for security use in general. It is meant to drive user experience for relying parties which want to eliminate passwords, but need a durable credential by which to replace them.

(i) to have the option to request attestation and to have a description in the related MetadataStatement whether this authenticator supports multi-device keys in general or not

The device public key attestation would presumably let a relying party know that an unapproved implementation has gained control of the private key and is attempting to use it. Depending on the policy this might cause this one authentication request to be rejected, additional user challenges to be made, or the public key credential itself marked as no longer trusted.

Note however that if the backup mechanism does allow arbitrary authenticator access, they may go from one 'authentic' device owned by the user to another equivalent 'authentic' device controlled by a malicious party.

@timcappalli
Copy link
Member

The device public key extension, sent on registration and on use, effectively allows one to make judgements both based on the details of the device and on the backup/restore mechanism.

I'm not following this. There's no relationship between these bits and the DPK.

@dwaite
Copy link
Contributor

dwaite commented Feb 18, 2022

I'm not following this. There's no relationship between these bits and the DPK.

Which bits? I'm speaking to the underlying implementation details of the asserted authenticator.

@rmondello
Copy link

Apple likes the proposal.

@Firstyear
Copy link
Contributor

Someone from apple contacted me directly to discuss, and it turns out there was a second bug in safari related to attestation and platform syncing, where my device was behaving incorrectly and creating a device-bound key with attestation even when sync was requested. That's what led to the confusion as it appears apple have an undocumented behaviour where passkeys do NOT respond to any attestation requests, but if sync is disabled, they will then allow attestation to proceed.

As a result, my concerns about currently existing passkeys are invalid, meaning that the proposal "as is" is good to go then. Sorry for the pain @timcappalli :(

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

Successfully merging a pull request may close this issue.