views:

1192

answers:

3

Applications send out emails to verify user accounts or reset a password. I believe the following is the way it should be and I am asking for references and implementations.

If an application has to send out a link in an email to verify the user's address, according to my view, the link and the application's processing of the link should have the following characteristics:

  1. The link contains a nonce in the request URI (http://host/path?nonce).
  2. On following the link (GET), the user is presented a form, optionally with the nonce.
  3. User confirms the input (POST).
  4. The server receives the request and
    • checks input parameters,
    • performs the change,
    • and invalidates the nonce.

This should be correct per HTTP RFC on Safe and Idempotent Methods.

The problem is that this process involves one additional page or user action (item 3), which is considered superfluous (if not useless) by a lot of people. I had problems presenting this approach to peers and customers, so I am asking for input on this from a broader technical group. The only argument I had against skipping the POST step was a possible pre-loading of the link from the browser.

  • Are there references on this subject that might better explain the idea and convince even a non-technical person (best practices from journals, blogs, ...)?
  • Are there reference sites (preferably popular and with many users) that implement this approach?
    • If not, are there documented reasons or equivalent alternatives?

Thank you,
Kariem


Details spared

I have kept the main part short, but to reduce too much discussion around the details which I had intentionally left out, I will add a few assumptions:

  • The content of the email is not part of this discussion. The user knows that she has to click the link to perform the action. If the user does not react, nothing will happen, which is also known.
  • We do not have to indicate why we are mailing the user, nor the communication policy. We assume that the user expects to receive the email.
  • The nonce has an expiration timestamp and is directly associated with the recipients email address to reduce duplicates.


Notes

With OpenID and the like, normal web applications are relieved from implementing standard user account management (password, email ...), but still some customers want 'their own users'

Strangely enough I haven't found a satisfying question nor answer here yet. What I have found so far:

A: 

I generally agree with you with some modification suggested below.

  1. User registers at your site providing an email.
  2. Verification email is sent to the users account with two links: a) One link with the GUID to verify the registration b) One link with the GUID to reject the verification
  3. When they visit the verification url from their email they are automatically verified and the verification guid is marked as such in your system.
  4. When they visit the rejection url from their email they are automatically removed from the queue of possible verifications but more importantly you can tell the user that you are sorry for the email registration and give them further options such as removing their email from your system. This will stop any custom service type complaints about someone entering my email in your system...blah blah blah.

Yes, you should assume that when they click the verification link that they are verified. Making them click a second button in a page is a bit much and only needed for double opt in style registration where you plan to spam the person that registered. Standard registration/verification schemes don't usually require this.

Andrew Siemer
Thank you, Andrew. I have left out some assumptions to reduce the length of my post, but I will add that information. In general, GUIDs should not be used as random keys, as they are designed for uniqueness not secure randomness. I agree that the additional user action should not be necessary, but performing the action directly on the GET request is not nice from an architectural view.Do you have any references on 'standard registration/verification schemes'?
Kariem
+3  A: 

This question is very similar to Implementing secure, unique “single-use” activation URLs in ASP.NET (C#).

My answer there is close to your scheme, with a few issues pointed out - such as short period of validity, handling double signups, etc.
Your use of a cryptographic nonce is also important, that many tend to skip over - e.g. "lets just use a GUID"...

One new point that you do raise, and this is important here, is wrt the idempotency of GET.
Whilst I agree with your general intent, its clear that idempotency is in direct contradiction to one-time links, which is a necessity in some situations such as this.

I would like have liked to posit that this doesnt really violate the idempotentness of the GET, but unfortunately it does... On the other hand, the RFC says GET SHOULD be idempotent, its not a MUST. So I would say forgo it in this case, and stick to the one-time auto-invalidated links.

If you really want to aim for strict RFC compliance, and not get into non-idempotent(?) GETs, you can have the GET page auto-submit the POST - kind of a loophole around that bit of the RFC, but legit, and you dont require the user to double-optin, and you're not bugging him...

You dont really have to worry about preloading (are you talkng about CSRF, or browser-optimizers?)... CSRF is useless because of the nonce, and optimizers usually wont process javascript (used to auto-submit) on the preloaded page.

AviD
Thank you, for the pointer AviD. Good solution to have javascript on the first page submit the POST. That does not bug the user and conforms to the RFC. I thought of the browser pre-loading a URL that is displayed in the body of a webmail client. This would definitely not execute javascript code at the target web page. This is a good proposal ... do you have any references where something like that is implemented?
Kariem
Right now, I could only think of references at some of my consulting clients (which I can't really disclose)... I don't really bother noticing other sites anymore... Sorry.
AviD
+1  A: 

About password reset:

The practice of doing this by sending an email to the user's registered email address is, while very common in practice, not good security. Doing this fully outsources your application security to the user's email provider. It does not matter how long passwords you require and whatever clever password hashing you use. I will be able to get into your site by reading the email sent out to the user, given that I have access to the email account or am able to read the unencrypted email anywhere on its way to the user (think: evil sysadmins).

This might or might not be important depending on the security requirements of the site in question, but I, as a user of the site, would at least want to be able to disable such a password reset function since I consider it unsafe.

I found this white paper (I wanted to post the Google cached version as well for future reference but SO will not allow me to use more than one link, sigh) that discusses the topic.

The short version of how to do it in a secure way:

  1. Require hard facts about the account

    1. username.
    2. email address.
    3. 10 digit account number or other information like social security number.
  2. Require that the user answers at least three predefined questions (predefined by you, don't let the user create his own questions) that can not be trivial. Like "What's your favorite vacation spot", not "What's your favorite color".

  3. Optionally: Send a confirmation code to a predefined email address or cell number (SMS) that the user has to input.

  4. Allow the user to input a new password.

Per Wiklander
I am not sure, whether I have fully understood your answer, but I believe it misses the point: 1) The password is never sent out in any email. That has neither been suggested in the question, nor in any of the answers. 2) Additional security measures, such as account number and verification questions not considered at all, because that is a different subject. 3) The question asked for a solution for password reset using a confirmation code, which is actually a part of your solution: item 3 in your summary. Could you please elaborate on how your answer helps in the context of the question?
Kariem
1) The original question was "What are best practices for activation/registration/password-reset links in emails with nonce". In my answer I tried to point out that using "password-reset links in emails" is not a good idea. The password is never sent out, but the link that is sent out is just as good as a password since it gives access to the account and lets the attacker change the password giving him total control of the account.2) The "additional security measures" was my suggestion of a better way of doing a password reset since I had said that the email reset was a bad way.
Per Wiklander
3) The process of sending a confirmation code through email or SMS would only be initiated AFTER the other identification method had succeeded. It should not be relied upon as the only required identification method.
Per Wiklander