The modern email/password authentication does not protect users from bad practices and, in the secure version (with 2FA), is difficult to use.
The IT world needs more discussion about authentication mechanisms to find more convenient and secure options.
This proposal contains an unusual authentication for a small subset of use cases. What problems does it have in terms of security and usability?
RSS reader that runs entirely locally (local first) using the cloud only for data synchronization between clients:
- Will be used daily, often from both a laptop and a phone.
- The data (subscription list) is not critical to be lost.
- Will be used by users with different technical levels.
- The server must not know anything about the user.
- The server and the client are open source (but only the client code can be 100% verified).
- We must work as a web app in modern browsers.
There are two buttons on the landings: “Sign in” and “Try without registering.” If the user selects “Try…”, the client assigns a random userId
and start a UI with saving the data locally.
The upper menu immediately warns the user that they need to register to access from different devices.
When you click on the Sign-Up button, the app generates an authorization key and an encryption key and generates long shared key ${ userId }-${ accessSecret }-${ encryptionSecret }
.
The app asks the user if they have a password manager (in a note telling what it is and why they should use it).
- If there is no password manager, the app asks the user for their email address. The server sends an email with the key and recommendation to write down the key somewhere and not delete the email but to archive it (since we don’t have the password recovery). The server does not save the email/key anywhere.
- If there is a password manager, the app shows the key and suggests that the user saved the key into a password manager (explaining that we don’t have any password recovery).
The app saves userId
and encryptionSecret
are to localStorage
and accessSecret
as HttpOnly
cookie (no longer visible from JS). userId
and accessSecret
are saved on the server, but the encyptionSecret
server never knows.
The user clicks “Sign in” and enters their key by taking it from the password manager or by finding an email from his registration.
The app connects to the server using userId
and accessSecret
and downloads encrypted data, which it decrypts locally using encyptionSecret
. If the app needs to save something on the server, the data is encrypted again and uploaded to the cloud.
If the user has forgotten the key, there are two options
- Search the mail client for the letter with the key (using a unique word that is only in the text of the registration letter).
- Take another client that is already logged in and restore the key in it. The user can optionally add a fingerprint to access
encryptionSecret
. The server will tellaccessSecret
only after adding a note to the log about key restoring.
However, if the user deleted the email and lost all the logged clients, the data will be lost. We assume that the subscription list is not so critical, and it is normal to lose it in rare cases.
- User uses one password on all websites, and it leaked. This attack does not work on our method, as we generate the key ourselves.
- Our servers were hacked. Our server has no
encyptionSecret
, the data is completely anonymous and encrypted. - XSS attack on the web client. JS won’t have access to
accessSecret
. - MitM attack between client and server. Data cannot be decrypted without
encyptionSecret
. - Trojan on the client machine. Here we can only hope on apps isolation in the OS, but the full key is likely to be leaked.
- The user’s device is stolen. A user through another client can change
accessSecret
andencryptionSecret
by resetting all clients. - A family member gets access while the user is sleeping. After recovering the key, the client shows a warning for a couple of days that the key has been recovered.
- Malware code on the server, which sends emails with the key. We assume that the “no password manager” way has some compromises.
- Non-standard system for the user. We first let the user try an application. They have the motivation to go through a complicated process.
- We give a couple of ways to restore access, but the user can lose access.
What other attack vectors or UX problems do you see?
A "Key encrypting Key" can be used to avoid client side encryption while keeping stuff safe. Also it adds the ability to close other sessions.
Here's a draft: https://gist.github.com/subzey/dd2a68c1a88b87c3ee7e160da6b91148