- 
                Notifications
    
You must be signed in to change notification settings  - Fork 239
 
Description
There are password managers (e.g., Bitwarden) where one of the primary security guarantees is that the vault key is never sent to the server. When unknown CBOR key-value pairs are ignored in the authenticator data and an authenticator is used that includes the PRF outputs in the authenticator data, one cannot simply scrub out such key-value pairs since the authenticator data is part of the signature. This causes the vault key to be sent to the server violating one of the security guarantees.
I propose that the spec should explicitly forbid authenticators from including the plaintext PRF outputs in the authenticator data. It's less important for CTAP-based authenticators to have this requirement since hmac-secret is encrypted; however nothing forbids such an authenticator to embed some other key-value pair and still be FIDO and WebAuthn compliant. At the very least though, non-CTAP-based authenticators should be required to not send the plaintext PRF outputs instead of simply saying:
Authenticator extension input / output
This extension is abstract over the authenticator implementation, using either the [FIDO-CTAP]
hmac-secretextension or an unspecified interface for communication between the client and authenticator. It thus does not specify a CBOR interface for inputs and outputs.
I think it should say something like (emphasis added):
Authenticator extension input / output
This extension is abstract over the authenticator implementation, using either the [FIDO-CTAP]
hmac-secretextension or an unspecified interface for communication between the client and authenticator. It thus does not specify a CBOR interface for inputs and outputs except that the CBOR outputs must not contain the plaintext PRF outputs.
Recently Google Password Manager (GPM) was changed since it was sending the following CBOR map in the authenticator data when PRF was requested:
{
  "prf": {
    "eval": {
      "first": <first input passed to PRF>,
      "second": <second input passed to PRF>
    },
    "enabled": true
  }
}This was changed so that it wasn't sending the eval key-value pair anymore. In this case it wasn't a problem since the data that was being sent were the PRF inputs; but even if it were sending the PRF outputs, it wouldn't violate the spec. Should be noted that the spec explicitly mentions how PRF can be used for "encryption keys" but only states the importance of removing the PRF outputs from the client extensions:
For some use cases, for example if PRF outputs are used to derive encryption keys to use only on the client side, it may be necessary to omit this results output if the PublicKeyCredential is sent to a remote server, for example to perform the procedures in § 7 WebAuthn Relying Party Operations. Note in particular that the RegistrationResponseJSON and AuthenticationResponseJSON returned by PublicKeyCredential.toJSON() will include this results output if present.
Without the spec forbidding plaintext PRF outputs from being sent in the authenticator data, password managers can't realistically use PRF for vault encryption unless they only allow PRF for CTAP-based authenticators or use attestation and enforce that only certain authenticators are used that have been tested to not include such data in the authenticator data.