w3c / webauthn

Web Authentication: An API for accessing Public Key Credentials
https://w3c.github.io/webauthn/
Other
1.19k stars 172 forks source link

Authenticator session not possible for BLE #649

Closed jovasco closed 6 years ago

jovasco commented 7 years ago

An authenticator must maintain isolation between sessions. It may do this by only allowing one session to exist at any particular time, or by providing more complicated session management.

This is not possible with CTAP BLE Authenticators. They do not have a concept of a session nor is there any way to distinguish which client on a particular platform is talking to them.

emlun commented 7 years ago

Apart from the authenticatorCancel operation, I think a session can be understood to span only a single operation. Do CTAP BLE authenticators have a cancel command, and if so, how is it authenticated?

jovasco commented 7 years ago

They do and it is not authenticated.

jovasco commented 7 years ago

I believe most clients will start with a getInfo command before even issuing a specific command.

emlun commented 7 years ago

Do CTAP BLE devices require some kind of pairing before use, and can they be connected to more than one client at a time?

As far as I know the only state that is ever stored in a session is which operations are currently underway, in order for authenticatorCancel to work, so you should be good if the authenticator can refuse to perform more than one operation at a time.

jovasco commented 7 years ago

Yes, they require pairing and encryption for the link. But the link is with the device the clients are running on (referred to as "platform" above), not the clients themselves. It is not possible for the authenticator to distinguish between commands from two clients on the same device.

jovasco commented 7 years ago

For the record, I am merely pointing out that the current language is strictly speaking not compatible with the current BLE authenticator CTAP protocol definition.

I am not arguing to change the BLE CTAP specifiction. From my p.o.v., multiple sessions are more of a problem than a feature since it is often impossible to see on the authenticator which request you are approving.

emlun commented 7 years ago

Yes, I understand that. But none of this is really relevant if the authenticator doesn't allow more than one operation at once, is it? If one client initiating an operation locks the authenticator for all other clients until that operation finishes or is aborted, then that satisfies the webauthn spec.

(Technically, different clients could cancel each other's operations, but they would then be violating the spec since they shouldn't do that unless they know they have an operation running)

jovasco commented 7 years ago

The problem is that the authenticator also does not have a way to send feedback to a specific client. So if client A has an operation running and client B issues a command, the error return value is returned to both clients, effectively cancelling both. This is, however, not explicitly documented in the current BLE CTAP afaik ( https://github.com/fido-alliance/fido-2-specs/issues/366 ).

emlun commented 7 years ago

Is it also impossible for the client to discern whether a given response/error corresponds to a command sent by that client?

jovasco commented 7 years ago

Yes.

emlun commented 7 years ago

In that case I suppose it's up to the host driver to not allow more than one client at a time to communicate with the authenticator. I feel like that should probably be included in the CTAP spec, what do you think?

jovasco commented 7 years ago

Although I think that would be an excellent solution to the technical issue, I think it is unrealistic for the WebAuthn or the CTAP spec to try and create requirements for host Bluetooth driver stacks.

Why was this language included in the WebAuthn spec?

emlun commented 7 years ago

Ok, I have to admit I know almost nothing about how Bluetooth stacks or drivers work.

I wasn't around when this language was added to the spec, but my understanding is this:

Although I suppose the issue of authenticators being left locked indefinitely could be somewhat solved by a required timeout.

Anyway, since there can be more than one client running on a device there must be a way to handle concurrent commands by different clients that don't know about each others' running operations. If a client B tries to send a command to an authenticator currently processing a command send by client A it MUST either

  1. result in an error returned to B alone (otherwise A could falsely interpret the error as A's operation having failed, rather than B's operation being refused), or
  2. result in an error which A can identify as not corresponding to A's operation (otherwise A could falsely interpret the error as A's operation having failed, rather than B's operation being refused), or
  3. be queued by the host driver (outside the client) to run as soon as the authenticator becomes available, or
  4. be queued by the authenticator to run as soon as it's available, or
  5. be run on the authenticator in parallel with A's operation.

Clearly for BLE CTAP authenticators, and I expect for most authenticators, neither (4) nor (5) is an option. The remaining options are then that some layer between the client and authenticator, like an OS driver or the like, must do (1), (2) or (3); the choice shouldn't matter much, if at all, to the client.

If none of those is an option, we'll have to eliminate the authenticatorCancel operation and rely exclusively on timeouts. This seems to be how U2F handles the issue. It could be workable, but it'll likely make for a confusing user experience.

Modifying the WebAuthn spec to make authenticator responses include some kind of request ID would break backwards compatibility with U2F, since the client in general does not have access to the credential public key and therefore cannot verify what an authentication response message has signed over.

jovasco commented 7 years ago

Thank you.

The main problem that this approach does not address is that for most authenticators, it isn't possible to see which operation you are approving. So even if there is multiple session support and the clients know which session the authenticator is currently handling, the user does not. I consider this a security issue more than a usability issue.

If there are two clients trying actions simultaneously, it might not even be possible for the user to see this. On USB, there would be, at best, a slight hesitation in the blinking of the authenticator between two operations (perhaps even hidden by his finger during UP). The user is likely to assume his touch failed and touch again, approving both. For NFC, it might very well be that your card is in the NFC field long enough for both operations to complete (and card presence is sufficient for UP in the NFC case).

I haven't tried in a while but at some point Chrome terminated all U2F sessions if the browser window lost focus, which is a practical solution to the issue.

As for BLE, if two clients collide, both will fail: a much better solution from a security point of view. As for usability, this is only a problem if the user initiates two logins at the same time and the client can detect this by the error that is returned. There are several well-understood strategies to handle such collisions.

I believe it would be better to change the session wording here in WebAuthn to allow for session collision to fail both sessions than trying to push this down into CTAP. It will require invasive changes to the BLE CTAP protocol to add support for this.

emlun commented 7 years ago

Those are all very good points. On second thought I also think my concern about a confusing user experience is a minor one - the majority of users will likely have only one authenticator, or use only one at a time, so it shouldn't be too big an issue in practice. After all, I haven't heard about anyone complaining about this regarding U2F; I've only thought about it myself while testing interop with 3-4 authenticators plugged in.

Failing both requests in case if collision does seem very sound. I'm starting to think that's preferable to the options I described above, and that perhaps it's not actually a bad thing if the cancel operation cancels everything regardless of where the requests originated. As you say, it's probably better to err on the side if caution and prefer failing requests rather than risking that the user unwittingly authorizes unintended requests.

[Emphasis added by @equalsJeffH 2017-10-18]

equalsJeffH commented 7 years ago

cc: @christiaanbrand @leshi @jcjones @AngeloKai @rlin1 -- do you agree with @jovasco and @emlun's assessment that "Failing [the colliding] requests in case if collision does seem very sound." ?

If so, which milestone should we attach this to? CR or WD-07 ?

AngeloKai commented 7 years ago

My understanding is that all browser vendors implement some sort of safeguarding mechanism to deal with race conditions. But it is too difficult to write down what we should do until we have further testing. Given this information, I am assigning the issue to PR until after the implementers know what they want to do and can write it down in the spec.

@equalsJeffH @nadalin

jovasco commented 7 years ago

@AngeloKai The problem is not internal to browsers but to collisions of multiple browsers or other clients.

In any case, the current language makes it impossible to use the BLE transport, so perhaps a temporary fix for that until this can be sorted out?

equalsJeffH commented 7 years ago

@jovasco wrote:

the current language makes it impossible to use the BLE transport

Well, it is not "impossible"; rather, one needs to figure out what "works" in such a BLE "colliding requests" situation, and then we can update the spec as appropriate.

So perhaps we ought to add a "Note:" or "Issue:" at that "An authenticator must maintain isolation between sessions" statement in the spec, and indicate that implementers should experiment with various approaches and report back to the working group?

jovasco commented 7 years ago

@equalsJeffH which is exactly what I am asking for.

There is no solution at BLE level possible without changing the transport.

emlun commented 6 years ago

You said earlier that a BLE authenticator will throw an error to all clients if it receives a new request before it has returned the first. IMO that's a perfectly valid way to "maintain isolation between sessions", but I agree with adding the clarification proposed in #688.

nadalin commented 6 years ago

Closing this issue since there are IPR issues with @jovasco joining this WG