Most security experts seem to agree that passwords are on the way out. There is good reason for this:
- Users pick awful passwords, making brute force attacks easy.
- Users reuse passwords, making credential stuffing effective.
- Users can’t remember good, unique passwords for more than a few sites.
- Passwords can easily be phished.
- Passwords are exposed to the server. This makes reuse worse and offline phishing possible.
A wide variety of new approaches are vying for popularity. WebAuthn removes passwords and instead uses keys that are managed by the browser. Email “magic links” use the ability to receive email as authentication. SSO delegates the problem to another provider. However these approaches all have major downsides. Let’s take a quick look at some of these and try to squeeze them into a pass/fail score, ignoring most of the nuance.
- No Memorization
- This means that the user doesn’t need to remember anything. Or at worst only remember a single, relatively short, thing for all sites. (Like an SSO URL or a master password)
- No Third Party
- This means that only the user and the service are involved. No third party needs to be available, and no third party can impersonate the user. (The WebPKI is excluded here)
- Decentralized
- This means that all third parties can be arbitrarily selected by the user.
- No PKI
- This means that WebPKI is not relied upon.
- Unphishable
- This means that the user can’t be tricked into giving someone else access to their account when they try to log into their account.
- Syncable
- The user can easily log in on all of their devices that are set up with their tools and config.
- Transferable
- The user can easily log in on a new device that doesn’t have their tools or config available.
- Mutual
- The user also verifies the server.
- Leak-Proof
- The server never learns enough information to authenticate as you to someone else.
Method | No Memorization | No Third Party | Decentralized | No PKI | Unphishable | Syncable | Transferable | Mutual | Leak-Proof |
---|---|---|---|---|---|---|---|---|---|
Passwords | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
WebAuthn | ✅ | ✅ | ✅ | ✅ | ✅ | 1 | ❌ | ❌ | ✅ |
Magic Link | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | 2 | ❌ | ✅ |
SSO | 3 | ❌ | 4 | ❌ | ✅ | 3 | ❌ | ❌ | ✅ |
TLS Client Certificate | ✅ | ✅ | ✅ | ✅ | ❌ | 5 | ❌ | ❌ | ✅ |
- Possible but not currently available. Can be blocked by the server if desired.
- It is transferable if and only if you have an already-logged-in device available and the service allows following the link on a different device than the one that is trying to log in.
- SSO just shifts the end-user authentication to someone else, so the method that the someone-else uses you determines these features.
- Possible, but generally just a couple whitelisted options are available. (RIP OpenID)
- Possible but not widely available.
Personally I prefer to use passwords wherever possible. With a password manager (I use Firefox’s built in one) I know that I have strong passwords, they are synced across all of my devices, and they are only auto-filled on the correct sites. I don’t depend on any third party service (other than Firefox Sync which gracefully degrades if offline or down and has no access to my passwords) and can relatively easy copy a password into another device manually if required. It is also incredibly convenient, I don’t need to leave my browser or redirect to any other sites, I only need to click the login button because my credentials are autofilled.
So a password manager that integrates with the browser solves password problems 1-4. The only remaining flaw is that the server still sees my password. What if we could make passwords more secure rather than replacing them? One solution is a Password Authenticated Key Exchange (PAKE). If added to the above table and used with a password manager all boxes would be checked!
Possible Implementation
A very simplistic approach would look like follows:
<form action=/login>
<input type=text name=username>
<input type=password pake></input>
<button>Login</button>
</form>
A browser that supports the pake
attribute would treat this very differently from a regular password field.
- The value can not be accessed by the page in any way.
- When the form is submitted the browser will not send the password to the server. Instead, it will do a PAKE exchange with the server. Probably using OPAQUE with TLS or a similar mechanism.
- The browser will remember that this password is PAKE-protected and refuse to autofill it in any way that is accessible to the website.
- The UX will probably be subtly different. For example the browser would push harder for password-manager use (either built-in or extension based) and random password generation. Eventually non-PAKE password fields will probably show warnings.
Unanswered Questions
- Need a solution for signup. For aPAKE algorithms this should never expose the password to the server. Maybe new a new form field? Switching behaviour on
autocomplete=new-password
seems wrong. Maybepake=login
vspake=register
? - Need to negotiate the algorithm used with the server.
- Need to support upgrading passwords to better algorithms over time.
- Should we specify the algorithm in the HTML, or just let the browser and server negotiate the best algorithm?
- How do we know what the
username
field is? It needs to be transmitted before password validation and the rest of the form (which should probably only be transfered after authentication). - What if someone manages to MITM or otherwise compromise the service? I think a lot of phishing concerns need to be considered here, but at the end of the day, the password manager loudly protesting and requiring explicit warning dismissal before filling a previously-PAKE password into a non-PAKE location should sufficiently prevent this.
- Does it make sense to have older browsers that don’t understand the attribute fall back to plain-text? Or would it be better to use a new element that wouldn’t work on browsers that don’t support it? I think that allowing the graceful upgrade is probably the better option.
- Is a JavaScript API needed? Maybe the JS could manage the credential behind an opaque reference and make an API call with it. However this means that the page before authentication can see the results so is somewhat trusted. For best security a full page reload on a new, authenticated connection should be required. What if a “client” site wants to use PAKE authentication to two backend APIs (for example a Matrix client with multi-account support)?
TL;DR
It seems to me that we are trying to get rid of passwords with solutions that miss some basic UX, flexibility, decentralization and security properties. I find myself often wondering if it would be better to stick with passwords as the user-visible authentication method but improve the underlying protocol to provide better security.
Top comments (2)
I don't think that passwords are needed at all. The reason they exists is to verify that you are you. There are better way of doing it. But I yet to see good solution.
The problem the password solve is that you say once that you're you and then again you verify that you're you.
I think that 2FA solution where 2nd A is the only A is the way to go. But it need to way better automated so it have better UX.
I was once thinking about Personal OAuth solution, where user browser act as OAuth provider that can verify that she is she. Or something like LastPass but that will allow to register to the service, not only store passwords.
All those password managers are just a patch/hack on broken system with password. It would be easier to just remove all password and start a better way of user authentication.
Solving password problem is great way to start a new Startup around the idea. Having app on a phone that act as OAuth with single button sign in like with physical Token would be really great idea for a startup that will get rid of passwords. Since with 2FA you actually don't need that 1st step with password. The app will only work similar to LastPass, Physical token and Authenticator App.
The flow can work like this:
To resister:
And you only need one password for the Service. This can be called 2ndFA Second Factor Authentication.
The normal process of registration with password and email will only happen with The Service.
I actually think passwords are ...troublesome. Mainly because of two reasons: phishing and password re-use. Sure, password managers avoid that, but it has its own risk too IMHO since it basically holds all your passwords in clear-text. If malware creeps in the device, I fear the "comfort" of the password manager will be your doom.
Somehow, the webauthn protocol is similar in idea. It's like your device bound password manager... But 1. it's protected by biometrics/PIN to "use" it each time and 2. you can never access the private keys themeselves, only sign payloads with it. It's simply more secure.
If I understand you right, your biggest gripe is syncing/transferability. While I also wonder if centralized/decentralized is an issue for you. Out of curiosity, what would you think about a solution like that: dev.to/dagnelies/registerlogin-wit... ?