It's a common practice for websites to send email verification links on sign up. Should these verification links expire? I know about a bunch of website where they do and I wonder why?
There isn't any major security reason behind them expiring. The main reason that this is done is to be able to clean up the database of old unused verification information.
From a UX side, some people argue that having a shorter verification time encourages people to verify sooner rather than later, but I haven't seen any evidence supporting that. It does however fit what I would expect in human behaviour.
If clicking the verification link automatically logs the user in, then yes, the verification link should expire.
Why? Because if the user's inbox is compromised a hacker can search for the verification email and then click the verification link to gain access to the user's profile on the website.
The question then is, when should the link expire. Maybe not immediately after clicking it, but for example 24 hours after the link has been clicked.
If you do not handle e-mail confirmation expiration, someone could register with someone else's e-mail address and never confirm it which would lock the e-mail of the legitimate user if he ever wants to register to your website.
If the user hasn't confirmed his e-mail address in the given length of time, you want to make it available again, in case it wasn't really his address or if he wants to register again later on. Consider the case where a user entered the wrong e-mail address by a mistake.
And while the true user with the email account can attempt to resend a verification email if the site allows for it, it would make a terrible experience for this back-and-forth.
If you do not need the expiration date in the email you should remove it. You should always strive to decrease friction for the user. Any information they do not need adds friction.
I went through this discussion just the other day and I'm questioning if anyone ever reads the whole message in a confirmation email in the first place.
The person who signed up most likely read a message after the sign up that they have to confirm their email and all they are doing now is trying to get access to their account. Most users are familiar with this process and will instantly click the link in the email and will never read the expiration date, and if they do they will probably ignore it.
An unaccepted invite that never expires is an unnecessary security risk. Perhaps it's not a security risk in a simple single-user application where the user/account/profile/etc.. doesn't exist until they sign up, but it definitely is a risk when it comes to accounts with multiple users or many applications where an account is setup on behalf of the user and may contain sensitive or private information (such as a login for a mortgage account). If the user never accepts the invite and an attacker later gains access to their email they can then gain access to the relevant account. Why bother leaving this attack vector open for users that aren't even using your software?! There isn't a one size fits all approach, but if there's any doubt I'd lean on the side of caution.
Someone might argue that once a user signs up if their email is compromised that the attacker could easily gain access to their account by changing their password. This is a separate issue and possibly a good reason to consider other security measures like two factor authentication.
If the link has expired, I think the user should first be taken to an informative page letting them know that the link has expired and then asked to log in to take them to the respective flow.
If the user is authentic, it gives them a good idea of what happened, leading to a good way to find design principle.