Skip to content

Instantly share code, notes, and snippets.

@ai
Created May 20, 2020 22:28
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ai/5e0a1975e2a0971c66232d33fd526dbf to your computer and use it in GitHub Desktop.
Save ai/5e0a1975e2a0971c66232d33fd526dbf to your computer and use it in GitHub Desktop.

Zero-knowledge Auth

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?

Task

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.

Requirements

  • 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.

Registration

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).

  1. 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.
  2. 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.

Login

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.

Recovering the key

If the user has forgotten the key, there are two options

  1. Search the mail client for the letter with the key (using a unique word that is only in the text of the registration letter).
  2. 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 tell accessSecret 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.

Possible Attack Vectors

  • 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 and encryptionSecret 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.

UX Problems

  1. Non-standard system for the user. We first let the user try an application. They have the motivation to go through a complicated process.
  2. We give a couple of ways to restore access, but the user can lose access.

The Question

What other attack vectors or UX problems do you see?

@subzey
Copy link

subzey commented May 21, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment