Password-less login
Update: We received a lot of feedback and wrote a continuation here.
During the creation of Find Work, we used Google Sign-In for quick prototyping. Now that we have launched, we need to support more than Google users so we are adding email-based login. After some thought, we have decided to build it in a password-less manner.
Sizing up the problem
We have a handful of reasons for going password-less so let’s go over all the factors:
Password-ful login
- Pro: Well-established UX convention
- Pro: No need to navigate between screens
- Con: If database is compromised and passwords are reused across sites, then attackers might be able to access more sites
- Con: Many screens (e.g. email validation, forgot password flow) leading to more development work, more chances for error, and larger surface area for attacks
Password-less login
- Pro: If database is compromised, then there are no password leaks
- Pro: Email validation comes free during sign up
- Pro: Less screens yielding less work and smaller surface area
- Potential UX issue: Might not have email access on intended device. Workaround is to send a link AND a typeable token (a la 2 factor authentication)
General concerns
- Leaking account existence via timing attacks (especially important for Find Work since we don’t want employers to find out employees are thinking about leaving)
- Using unpredictable tokens (i.e. email validation, forgot password, and password-less login all need these)
- Require reauthentication for important changes (e.g. email editing, see GitHub sudo mode)
Strawperson argument: Email access
Claim: If someone has access to email account, then they can login.
Rebuttal: This is possible in a password-ful login setup via the forgot password flow. Sometimes there are additional “security questions” but this is typically easily found information.
Strawperson argument: Browser extension
Claim: With this setup, I can’t login easily with my LastPass, 1Password, etc browser extension.
Rebuttal: This is a legitimate claim but it’s equally plausible to use an email integrated browser extension. Additionally, we persist sessions for 2 weeks since the last access so this shouldn’t be a showstopper.
Planned implementation/solution
With all our ideas on the table, here’s the high level details of our solution:
- Always look up account/send email via a queue (prevents timing attacks)
- Avoid predictable tokens via salting and hashing
- Store token in session to restrict brute force surface area
- Use time constant comparison for tokens (prevents timing attacks)
- Invalidate token on failure (1 try for link, 3 tries for manual entry)
- Invalidate token via expiration (15 minutes)
- First iteration: Require writing to
support
for important changes - Second iteration: Require recent reauthentication for important changes (e.g. within past 15 minutes)
and here are some quick mocks/prototypes to convey our solution visually:
Update: We received a lot of feedback and wrote a continuation here.
Attribution
- Find Work, our product https://findwork.co/ (shameless plug)
- Slack, my first exposure to password-less login/magic links
- Medium, another major service with password-less login
- Roll Safe meme, http://knowyourmeme.com/memes/roll-safe
- XKCD, http://xkcd.com/