My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more

Email Sign-In Links

Daniel Kopitchinski's photo
Daniel Kopitchinski
·May 9, 2016

My friend Sella Rafaeli, is on a crusade against usernames and passwords.

He makes some very valid points about the simplicity of allowing users to login without a username and password. As part of his efforts, he posted a proposal on the subject of Simple, Secure Sign-In Links

The gist of the post is that instead of maintaining a login system with a username and password, you could use a database-less login system based on a sign-in email sent to the user. The email would contain a link made out of:

  1. The user's e-mail (effectively used as a username)
  2. A time-stamp (which allows you to limit the links validity)
  3. A hash based token (SHA256 on the users email, time-stamp, and an application wide secret key).

The resulting link would be:

https://app.com/token_login?email=foo@bar.com&time=2016-05-09&token=2/7/FKubqJKOzzfECwkEESQ00VwngcrB3GGpJrnGcGI=

Using a hash to avoid DB storage reminded me a lot of the approach in Life in a post-database world: using crypto to avoid DB writes

Medium has also added sign-in emails but they use a database-dependent solution, and only send a token in their email link:

https://medium.com/m/callback/email?token=<token>

I have a few concerns with the email sign in approach, and some security issues specifically with Sella's implementation:

Email Security

The underlying assumption is that you and only you have access to your e-mail, and therefore you and only you will be able to click on the sign in link. This is a big assumption when it comes to e-mail. You might share your e-mail account with your secretary, family members or team members, but not want to share your Bank / Tinder / Twitter account with them. Your employer might have access to your emails, and nation state surveillance programs most likely have access as well. Email delivery is far from secure. It still lacks end to end encryption, there are many issues with email encryption and email privacy.

Some say, "if someone has access to your email, they can simply reset your password". That's very true - but resetting a password is something that leaves behind an evidence trail. If you've reset my password, I'll notice it the moment I'm unable to sign in again. And I'll probably get a "your password has been reset" email as well. If you just click on a link in my e-mail, I'll never know that happened.

Email Reliability

Email isn't reliable. If it was, we wouldn't have invented texting each other "Have you read my email?". Your mail could get lost anywhere along the way, filtered out by spam filters or dropped because of lack of storage space. According to SendGrid, Email Delivery is Never Guaranteed: "You can’t assume that your email is getting delivered. In fact, 20% of the time it doesn’t. Instead, your emails are either going missing in cyberspace or being delivered to the spam folder."

Single point of failure

Relying on email just to sign-in can lock users out of your system if their email provider is down. This is true for single sign on solutions as well, as we've just experienced with Google Auth.

Usability

As far as usability goes - I think email sign in links are pretty uncomfortable. Imagine the following scenario:

  1. I open your site.
  2. I get asked for my e-mail address. This step always requires a leap of faith. Am I going to be spammed with marketing emails from now on?
  3. I type my address in, and am now requested to check my email.
  4. I have to open a new tab (if my email isn't already open), or a new app (if I'm on mobile).
  5. I have to wait for your email. And email can be SLOW - It was never designed to be immediate. Sure, we often get an immediate experience thanks to high speed internet and well architected service providers, but mails can often take a few minutes to reach their destination. Are your users willing to patiently wait, refresh, wait, refresh, until the sign-in email arrives? How would your conversion rates suffer?
  6. I have to find your email among all the other emails in my inbox. (Assuming it hasn't been sent to the spam folder). They might be grouped in the same thread as previous sign in emails. Once found, I click on the link, and I'm returned to your website, in a different tab.
  7. I now have 2 tabs open on your website, so I have to close one. Especially if one tab thinks I'm logged in but the other doesn't.

All this hassle might not necessarily be simpler than just using a username/password, or a 3rd party single sign on solution.

Clutter

E-mail sign in links contribute to email clutter. With all the spam, marketing, newsletters and retention emails, it's easy to forget that email is still an important communication method for personal and work use. Sign in emails can be quite annoying if received often, and make it easy to miss other important emails.

Reduces user's natural defenses

I suspect that getting users used to logging in via a link in their email might make them a lot more vulnerable to phishing attacks. Signing in by opening a link send via email can be a risky habit to acquire.

Sella's proposal:

Expiration

Sella's suggestion provides a 7 day expiration. That's a really long time to have a link in my inbox that can give instant access to my account. Especially if there is no way to revoke the link if I accidentally forward it to someone, and links can be used more than once. Medium uses 15 minutes, which is probably the minimum they could allow given Emails reliability issues. Any less than that and the link might be expired by the time you click on it.

Using a Hash instead of a MAC

It's important to distinguish between a cryptographic hashing function and a message authentication code. While a lot of MACs are implemented using a secret key and a hash (and are named HMACs), they aren't the same! Misusing a hash as a MAC can lead to attacks such as a length extension attack. Simply chaining data and a secret key and then hashing the result isn't the correct way to perform message authentication checks. In this case, OpenSSL::HMAC would be a more secure choice than Digest::SHA256.

Timing Attacks

Comparing a MAC to an expected MAC can be vulnerable to a side channel attack known as a Timing Attack. Consider the following code from the original post:

def check_token(data)
  email, time, token   = data['email'], data['time'], data['token']  
  real_token           = Digest::SHA256.base64digest(email + time + APP_SECRET)
  within_7_days        = Date.parse(time) > Date.today - 7 
  (token == real_token) && within_7_days && email
end

Without knowing the value of real_token, an attacker can still guess it by exploiting time differences in string comparison (token == real_token). Normal string comparison first compares the length of the two strings, and if identical, compares the strings char-by-char. Returning false once it runs in to the first mismatch.

This means that:

"cccccc" == "bbbbbb"

fails on the first character, and takes less time to return than:

"bbbbbc" == "bbbbbb" 

which only fails when it reaches the last character.

These small timing differences can allow an attacker to guess the correct MAC code, character after character, simply by timing how long it takes the server to reject a given mac - rendering the entire authentication mechanism useless.

Follow up reads about timing attacks:

Conclusion

All of the above isn't to say I oppose sign-in links by email (or SMS for that matter). They can definitely improve user experience in some cases, and even improve security for users with easy to guess passwords. Carefully consider the use cases, complications and security concerns based on your product, your security requirements, user feedback and the concerns raised here.