Re: [webauthn] Review privacy concerns around error conditions (#2132)

## Enumeration of errors

The following errors may be thrown during [`get()`](https://w3c.github.io/webauthn/#sctn-discover-from-external-source) as of commit a871f796c591721c9556f119924ee29484b441f5 (2024-09-04):

During init:
- (If callerOrigin is an opaque origin): throw a "NotAllowedError" DOMException
- (If effective domain is not a valid domain): throw a "SecurityError" DOMException
- (If pkOptions.rpId is present) and (If pkOptions.rpId is not a registrable domain suffix of and is not equal to effectiveDomain) and (if the client supports related origin requests) and (Run the related origins validation procedure with arguments callerOrigin and rpIdRequested. If the result is false): throw a "SecurityError" DOMException
- (If pkOptions.rpId is present) and (If pkOptions.rpId is not a registrable domain suffix of and is not equal to effectiveDomain) and (if the client does not support related origin requests): throw a "SecurityError" DOMException
- (Extensions may throw unspecified errors): throw a (Unspecified error)
- (If options.signal is present and aborted): throw the options.signal’s abort reason


During lifetimeTimer wait loop:
- (If lifetimeTimer expires): throw a "NotAllowedError" DOMException
- (If the user exercises a user agent user-interface option to cancel the process): throw a "NotAllowedError" DOMException
- (If options.signal is present and aborted): throw the options.signal’s abort reason
- (If options.mediation is not conditional, issuedRequests is empty, pkOptions.allowCredentials is not empty, and no authenticator will become available for any public key credentials therein) and (Indicate to the user that no eligible credential could be found. When the user acknowledges the dialog): throw a "NotAllowedError" DOMException


Rearranging this as a map of errors to causes of that error, and assigning numbers to each for easy reference:

- "NotAllowedError" DOMException:
  - (NA17): During init: (If callerOrigin is an opaque origin)
  - (NA18): During lifetimeTimer wait loop: (If lifetimeTimer expires)
  - (NA19): During lifetimeTimer wait loop: (If options.mediation is not conditional, issuedRequests is empty, pkOptions.allowCredentials is not empty, and no authenticator will become available for any public key credentials therein) and (When the user acknowledges the dialog)
  - (NA20): During lifetimeTimer wait loop: (If the user exercises a user agent user-interface option to cancel the process)
- "SecurityError" DOMException:
  - (S21): During init: (If effective domain is not a valid domain)
  - (S22): During init: (If pkOptions.rpId is present) and (If pkOptions.rpId is not a registrable domain suffix of and is not equal to effectiveDomain) and (if the client does not support related origin requests)
  - (S23): During init: (If pkOptions.rpId is present) and (If pkOptions.rpId is not a registrable domain suffix of and is not equal to effectiveDomain) and (if the client supports related origin requests) and (Run the related origins validation procedure with arguments callerOrigin and rpIdRequested. If the result is false)
- (Unspecified error):
  - (X24): During init: (Extensions may throw unspecified errors)
  - (X25): During init: (If options.signal is present and aborted)
  - (X26): During lifetimeTimer wait loop: (If options.signal is present and aborted)


## Analysis

- **Concern 4:** (NA20) could cause an information leak that could identify the user without consent ([§14.5.2. Authentication Ceremony Privacy](https://w3c.github.io/webauthn/#sctn-assertion-privacy)). The information leak occurs if the Relying Party can distinguish between these cases:

  1. A named credential is not available.
  2. A named credential is available, but the user does not consent to use it.

  **Preconditions:**
  Both case (i) and case (ii) require that the client has first probed the authenticator for any credentials listed in `allowCredentials`.

  **Observations:**
  The only preconditions for (NA20) are that the client successfully runs through the initialization steps 1-20, then offers the user an option to cancel, and the user exercising that option. There is no precondition of probing for eligible credentials.

  **Conclusion:**
  (NA20) cannot cause an information leak that could identify the user without consent.

- **Concern 5:** (NA18) and (NA20) should be indistinghishable in order to not facilitate the information leak in Concern 4.

  **Observations:**
  (NA18) and (NA20) are already distinguishable, since (NA18) likely occurs around `options.publicKey.timeout` milliseconds after `get()` was invoked, especially if `options.publicKey.timeout` falls within the [recommended reasonable range](https://w3c.github.io/webauthn/#recommended-range-and-default-for-a-webauthn-ceremony-timeout).

  Since in Concern 4 we already concluded that (NA20) cannot cause the relevant information leak, the information leak cannot be made worse by (NA18) and (NA20) being distinguishable.

  **Conclusion:**
  (NA18) and (NA20) do not need to be indistinguishable. (NA18) can be safely changed to a distinct TimeoutError.


-- 
GitHub Notification of comment by emlun
Please view or discuss this issue at https://github.com/w3c/webauthn/issues/2132#issuecomment-2328645419 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 4 September 2024 11:20:37 UTC