DEV Community

Arnaud Dagnelies
Arnaud Dagnelies

Posted on

Webauthn - Progressive Logic/Flow

The problem

As discussed previously, the credentials in webauthn are device bound. Each device has its secret key stored locally and hence each device must be registered individually. This leads to three possible actions:

  • Register
  • Login
  • Add Device

However, using three such buttons in a UI would likely confuse most users. Instead, it is much nicer to present a single button like "Sign In/Up" and decide which action to take depending on the context.

  • If the email is unknown => send a registration link
  • If the email is known
    • If the device is known => authenticate directly
    • If the device is unknown => send link to add device

This represents the big picture. Let us dive into this in more details. Moreover, it is important to notice that this requires proper interaction between server and client side.

Only the server side can detect if the email is registered.
Only the client side can detect if the device is registered.

The logic in details

The first step is to know if this account exists.

GET /is-registered?email=...
Enter fullscreen mode Exit fullscreen mode

The response of this could also be used to adapt the buttons displayed on the login page.

But is it OK privacy wise? To allow anyone to check if some user is registered there? It turns out that even if such a direct call is not available, anyone could find it out through the next step anyway, by checking whether a login attempt or a registration is triggered. This is basically unavoidable since the only input is the e-mail.

If the e-mail is not registered, the next step is straightforward. Request to send a registration link to your e-mail.

POST /send-registration-link?email=...
Enter fullscreen mode Exit fullscreen mode

Otherwise, a challenge must be requested to attempt to perform a login. At this point, it is not known if the requesting device is registered.

GET /login-challenge?email=...
Enter fullscreen mode Exit fullscreen mode

Once you obtain the challenge and data associated with it, the webauthn protocol can be invoked to request biometrics/PIN and sign the payload. If it succeeds, great, you can complete the login process!

POST /login {webauthn-created-payload}
Enter fullscreen mode Exit fullscreen mode

If it fails, there might be multiple reasons that must be distinguished:

  • this device is unknown, none of the registered key IDs matches
  • the user failed to input the correct biometric/PIN
  • the user cancelled
  • there was an unexpected error

In case it is an unknown device, you can request a new registration link.

POST /send-registration-link?email=...
Enter fullscreen mode Exit fullscreen mode

The confirmation page

During the login process with GET /login-challenge?email=..., a short lived challenge is perfect. For registration, something more long lived might be desirable. There is no clear cut rule about this, it is rather something to put into consideration.

The email could look like this:

Click here to register your device: https://.../confirm#{payload-including-challenge}

This page would then invoke the webauthn protocol with the provided challenge. Once succeeded, a simple registration call would complete the process.

POST /register-device {webauthn-created-payload}
Enter fullscreen mode Exit fullscreen mode

This same endpoint could be used for both initial registration or adding separate devices.

Managing devices

The main difference with traditional authentication is that the webauthn protocol is device bound. As such, one of the important aspects would also be to manage the devices. This is especially important to block a device if it is stolen. The minimal additional endpoints could be as follows.

GET /devices
DELETE /devices/{id}
Enter fullscreen mode Exit fullscreen mode

Of course, the devices are only added using the confirmation link.

Security

Here are a few last words about security. Both initial registration and later sign ins are two factor authentication. They both require your device and either biometrics or PIN. That's great.

Ironically, registering an additional device as described here is the weak spot. In this case, a hacked email account could enable the hacker to register its own device.

Security wise, registering a new device is the place were an additional verification (like a password, question/answer or SMS) would make most sense.

Discussion (0)