RFC: Multi-factor authentication #883
maximelebastard
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
Multi-factor authentication often consists in typing a code from Google Authenticator or a text message after a correct username/password combination submission.
It is the most efficient method to prevent attacks based on leaked credentials or phishing which implies that the attacker is owning correct credentials without too much login attempts.
This RFC is about supporting Multi-factor authentication.
New challenge concept
A new Challenge concept could be added to the library. It would be linked to a Key and it would represent an additional step to solve before getting a session issued
Types of challenges that could be supported
The following challenges are common and could be implemented
TOTP
The TOTP protocol (mostly known as "Google Authenticator code") consists in generating a shared secret between the server and a code generator (Authy, Google Authenticator...).
A rotating code (often 6 digits) would be provided by the app to the user and change every 30 seconds.
The user would solve the challenge by providing the code from his code generator.
The server would check the challenge by comparing the code with his own generated code.
Libraries like otplib could help for that one.
Attributes to store: the TOTP secret
Code through messaging
A text message MFA consists in sending a temporary code through a Text message (SMS, What's App, Messenger, Push notification...) to a pre-configured device on the user account. This is often used by people not confortable enough to install a TOTP generator. The generated code can be based on TOTP (which avoids to store the code directly but only the shared secret).
The user would solve the challenge by providing the code from his text message.
The server would check it using the TOTP protocol.
Big gotcha on this: as messaging often costs money, the check can cost thousands if no rate limiting is implemented (#882 ;-) )
Attirbutes to store: the TOTP secret, the user phone/push token
Emergency code
People often lost things, typically their phone. In order to gain access to their account without their phone, services like Github or Google often provides them Emergency codes they have to print. It is often 10 codes of 12 characters that are not rotating but allows to access the account again. A code cannot be used twice as it would be an absolute cheat-code for an attacker.
The user would solve the challenge by providing a valid and not used emergency code
The server would check it by comparing it to the database. If the code is valid, it would be removed from the database.
Attributes to store: a list of emergency codes
Webauthn
A cheap and very reliable method is to use TouchID, FaceID, Windows Hello or whatever platform authenticator through webauthn (Even banking use this in Europe to comply to PS2).
The user would solve the challenge by providing an AttestationObject in response to a previously registered PublicKeyCredential. This attestation object is provided by the user device derived from an internal (FaceID, TouchID...) or external (Fido U2F key...) private key.
The server would check it by comparing the AttestationObject provided by the user with the corresponding PublicKeyCredential stored in database.
Attributes to store: A big array of serialized PublicKeyCredential objects
Push + Click method
A new method used by apps like Google, Qonto or some other banks consists in receiving a notification on a phone previously enrolled. After opening the notification, we only need to tap a button on the mobile phone to validate the sign in on the main device.
This is very similar to the Code through messaging method, but here the verification comes from the server and not from the client which implies a different design.
The user would solve this challenge by clicking on the notification received on his device
The server would solve this challenge by calling a first callback to send a notification, and a second callback to wait for a remote endpoint/socket to confirm the access.
Attirbutes to store: the user phone/push token, some kind of webhook to listen for resolution
Scenario
5bis. The server waits a given delay for a remote server to validate the challenge
Main tasks to be supported by lucia
Side tasks to be supported or not by Lucia
Specificity / Extensibility
Lucia could provide a closed enum of challenges and support them out-of-the box. This would be easier for the developer, but has implication in terms of complexity, scope and weight.
On the other hand, Lucia could store arbitrary challenges linked to a key (key_id + json payload) and provide generic callbacks to start the challenge, wait for his completion on server side or validate user response from the client.
Maybe could it be an in-between, like for database adapters. This would allow to exteralize the weight of these dependencies and allow people to implement their own challenges as needed.
Priorization
I guess we could solve 80% of the needs by implementing TOTP and Emergency codes which are the easiests on the list.
Beta Was this translation helpful? Give feedback.
All reactions