Is emailing sign in links bad practice?

A magic link alone is not necessarily bad. A 512 bit entirely random value is going to be no easier to guess than a 512 bit private key. In general it is considered good practice to expire them after a reasonable amount of time. A good approach - which also avoids having to store database entries is to embed the token data in the url and sign it with a private key. I.e.

site.com/login?type=login&user=[username]&expires=[datetime]&sig=[signature of other parameters].

However email as a transmission mechanism isn't secure.

By default SMTP offers very little protection against interception. Traffic may be encrypted between servers but there are no guarantees. Even with encryption its still often possible to man in the middle the connection (encryption is not the same as authentication).

If so, then how is sending a link for password reset any more secure?

It isn't. This is why several services ask for some additional proof its you before sending the link (or after clicking it).


There are three problems here.

  1. As the documentation writes, email is not a secure protocol. Emails are stord in plaintext on the mailservers. The encryption between servers and between servers and clients is optional and beyond your control. And you are very likely not in a scenario where you can use any of the optional end-to-end encryption systems people built on top of email (PGP, S/MIME etc.). So you can not guarantee that nobody but the intended recipient will see the email in cleartext.
  2. Secrets do not belong into URLs. URLs appear in browser histories, in proxy caches, in server logs and many other places where you don't want secret information to appear.
  3. Users know how passwords work. It wasn't easy, but after a long struggle we finally got it into everyone's head that passwords must be kept secret. With your system, users might not be aware of what's the secret which is relevant for authenticating with your service. That makes them likely to mishandle that information and susceptible to social engineering attacks.

If you send links with a secret login token with email, then they should be single-use and expire rather quickly.