How Not to Do Web Site User Registration

The Internet is FULL of real life scenarios of how NOT to do web application security…it is unfortunate when a large, popular site shows the rest of the world some form of this inappropriate behavior. Unfortunate because it becomes both a HOW-TO for programmers, marketers, decision makers to repeat as well as an illustration of what NOT to do for the infosec community to harp on – both are undesirable.

Here’s a few screen shots I took while going through Account Registration on WordPress – this is a classic case study in what not to do.

While jumping through common hoops of account creation, WordPress required email address verification before activating my newly created account. After creating my account and waiting a few minutes, I was greeted with the following email requesting that I click on a link to verify that my email address did, in fact, belong to me:

Email notification of WordPress Account Activation Requirement

The names and email addresses have been removed to protect the innocent. This is pretty standard so far, no surprises – create an account, get an email, click the activation link, activate the account, login, good to go…

But then to my surprise, I’m greeted with the following Activation web page:
WordPress Credential Reminder

This is one of the very very few times I recall being shown both my user name and password on a web site. This can only mean that WordPress is storing my password in plain-text in their database or using reversible encryption – I suspect the former – plain text…with this knowledge I then glance up at the URL. *Sigh* – http:// – no ‘s’, meaning this was sent over the wire unencrypted for anyone paying attention as my credentials bounced from Columbus, OH up to Cincinnati, OH -back down to Atlanta, GA and then over to Dallas, TX – at first I wanted to kick myself – I should have been paying more attention to the activation email link and noticed  the lack of the ‘s’ and added it manually – but wait, why would I? I didn’t expect to be shown my credentials…this is not common.

Then I notice I have new Email…WordPress has also sent me an email notifying me that I have activated my account. View it in all its glory:Your Account has been Successfully Activated

Good GOD how many times do I need my credentials delivered to me over an unencrypted channel! Not to mention they managed in the email to group all information conveniently together – user name, password, AND login link…

I’ve seen flawed Password Reset schemes, but I think this might be the first poorly implemented Registration workflows I’ve run across and took notice.

Some quick tips for a more Secure User Registration:

  1. Perform all operations containing credentials (user name/password) over a secure connection. E.g. SSL/TLS
  2. Store passwords in the database using a one-way hash algorithm like SHA-1.
  3. Additionally, salt users password when generating the hash based on something unique to the user whose account you are protecting. The salt doesn’t have to a secret piece of information.
  4. If passwords must be recoverable (which should be a RARE requirement) store them using accepted open encryption algorithms – e.g. AES, 3DES.
  5. Never email a user their password.

Finally, I noticed that if you have my activation ID – without an authenticated session, you can go back and visit the activation page – anyone can now retrieve my email address and login name. Thankfully after the account is activated the first time, all subsequent requests do not reveal the password again, however, they do reveal my email address and user name which is completely unnecessary. Here’s what you see if you visit the activation page again after already activating your account:
What Subsequent Visits to the Activate Page Reveals
I’m going to add a 6th tip: There’s no need to keep telling the user they have activated their account once the activation key has been used- and there’s also no need to reveal the user name and email address to an unauthenticated user on the activation page – this only gives an attacker more information that they can use to reset the victim’s password and gain access to the account – for instance, when an attacker finds a valid activation id they could follow it up with a spear phishing attack to easily gain that final piece of information from the victim to compromise their account.

And here comes Tip #7: Since the activation page can be revisited and because the Activate ID is in the URL, this URL will be cached not only on the local users computer browser, but in web server logs, proxy server logs, router logs, firewall logs, etc. on potentially any system from here to Texas. If the activation key was discarded after first use or did not reveal any interesting information to begin with..who cares…but this is not the case.

While these features may be a benefit to users of WordPress (which is debatable, as it was overly repetitious), these features add an unnecessary level of Risk with little gain.

Also, I’d recommend going in and changing your WordPress password after registering – and hope they don’t email it to you again…they don’t appear to anyway…*fingers crossed*

* Update – it’s been over 16 hours and the activation link still works, revealing my user name and email – I’ll be checking back to see when it actually get’s removed. Additionally, I did not receive an email containing my updated credentials after I changed my password on WordPress…so the recommendation to change your password seems like a good one.

* Update 2 – Readers are reporting that WordPress does in fact hash the password, but only after mailing the plaintext one back to the user. And to clarify – many have suggested that WordPress is sending a randomly generated password. That is not the case. The password emailed to me was most certainly one of my creation.

Published by

Jason Montgomery

A Principal and Senior consultant for over 13 years at ATGi (www.atgi.com). I've worn many hats - Unix/Linux/BSD sysadmin, domain admin, network engineer, web developer, programmer, architect, DBA, consultant, security specialist, ethical hacker, and author. I've had the added benefit of straddling both the Microsoft Windows and Unix/Linux/BSD platforms and have extensive experience with .NET and I am the Lead Author for SANS DEV544 .NET Development course. Also, I had the pleasure of co-authoring Profession K2 blackpearl, (c) Wiley Press 2009 (WROX).

49 thoughts on “How Not to Do Web Site User Registration”

  1. Not being notified of password changes can be just as bad. You want to be notified if someone does manage to acquire enough of your credentials to be able to log in and hijack your account.

  2. not just your details either….

    thru google

    site:en.wordpress.com “your account is now active”

  3. You say never email passwords. I agree. What I have never understood is why mailing lists powered my Mailman (GNU mailing list manager) are often configured to email you your password every month. Why is this?

  4. Just for some clarification, WP just uses a one-way hash on your password but doesn’t generate it until you’ve activated your account. (or requested a new password)

  5. Regarding the plain text password, it’s also possible that they wait to encrypt the password until you have activated the account. That way they can email you the pw in the welcome email.

    If you look at the forgot password functionality you’ll see that it will generate a new password, so presumably they don’t have it in plain text any more after activation.

    Ofcourse it’s inexcusable to show the plain text password on the web page, but for email I think it’s pretty common to do so.

  6. This may be true for WordPress.com, but that’s why I would never recommend using (or relying upon) WordPress.com for anything.

    Download the software and set it up on your on domain on your own hosting account (or server) so that you can have complete control over everything.

  7. The same thing happened to me, from Safari Books Online, the O’Reilly service, which probably has a few books somewhere about not doing things like that.

    excerpt:

    Log on Today!
    1. Visit URL: http://my.safaribooksonline.com/mybookshelf

    2. Log in with your username and password:
    Username: XXXXXXXXXXX@gmail.com
    Password: XXXXXXXXXXXXXXX

    I got 3 emails like that (relative to a trial account).

    Now, I complained to customer service, and got a very neat “we implements the latest industry standard on multiple levels …”

    Despite this cleanly saying they weren’t going to act on that, I got another message two months later to inform me that they stopped sending people their passwords.

    Something is sure, I’m not all that eager to send these guys my credit card information.

  8. From the perspective of a user, if you suspect a company might do this I guess you have to use a throw-away password and then change it immediately.

    They still store your new one but I think it will have never been sent in the clear.

  9. Ditto on the SHA-1 recommendation, it’s not recommended for new crypto systems, use a SHA-2 variant instead, gee you could have figured this out with 2 minutes of googling.

  10. Actually, if you look at the wordpress source code you will see the password is NOT stored in the db, it’s a md5+hash of it.

    It only knows the plain text password that one time upon signup when it generates it and emails it to you, after that one page load, it’s gone.

    However this doesn’t mean that their entire process doesn’t suck by default, a user should be choosing their own password and then emailed the activation link, not emailed the password. It’s from old old old WordPress 1.0/1.5 legacy

    There are plugins to change this behavior however, ie. I wrote “Instant Password” for the bbPress side to stop the above registration nonsense and let the user choose their own password.

  11. The password in plain view is what I’m most concerned about, but I do think that WordPress uses a SHA-1 encryption algorithm… perhaps they create a randomized password, print that onto the screen, THEN encrypt that password and store it in the database.

    Yes, the security is pityful. But I don’t think it’s as terrible as it seems at first glance.

  12. The unfortunate thing is the same process comes in the downloadable version of WordPress. As of Aug. 2008, more then 2.8-million self-hosted sites were running the WordPress platform. What do you think the percentage is of those who have recognized this horrendous gap and done something about it?

    There are some articles, and plug-ins available if you’re looking for some fixes:
    http://maketecheasier.com/11-ways-to-secure-your-wordpress-blog/2008/08/12
    http://www.dailyblogtips.com/5-plugins-to-keep-wordpress-secure/

  13. A lot of websites do this when you register.
    Maybe you should do what most intelligent people do and change the default password they send you.

  14. Now seriously, noone expects any kind of super-security from WordPress or?

    It is very popular, despite using the ugly language PHP.

    Instead of complaining about bad security examples, we should realize that FEATURES come before security. And if anyone wants to dethrone WordPress, then they not only need to be better but need to include better security as well.

    A big challenge.

  15. This is why I have 3 levels of password.
    1 for sites I don’t know, 1 for sites I know but am not sure I trust, 1 for sites that I know and trust and really want to be secure.

    The final password is 26 characters, alphanumeric, uppercase and lowercase and symbols.

    I used to only have the first two… Then I used rainbow tables on my Active Directory Domain Controller, 8 char uppercase + lowercase = not enough without salting!

  16. SHA-1 is not recommended, use a safer hashing algorithm. Blowfish is good for password encryption. Also sending the password through mail isn’t that unsafe. You make it sound like the whole US could read your traffic, and that’s not the case.

  17. In my opinion, SHA-1 is still plenty secure for password hashing. The collision attacks are more dangerous for digital signatures. I would wait until there is a new standard (SHA-2? SHA-3?). Right now, you will have problems finding another hashing algorithm that is implemented as widely ( e.g. in PHP, you would have to install additional PEAR modules to get Blowfish support).

  18. I agree, except with point #4. If the password can be recovered at all, it’s usually not worth the extra work to encrypt/decrypt. If an attacker gets access to the database then he’d probably be able to figure out how to decrypt an encrypted pass. I believe the Pidgin IM client’s argument is similar to this, as they store your password in a plaintext file. It’d be nice if more services offered logins through hashes as an extra option to passwords which are then hashed and checked. Less work for the server, more security for the user.

    I haven’t made a wordpress account in a good while, but regardless I’m always shocked by this kind of behavior…

  19. “This can only mean that WordPress is storing my password in plain-text in their database or using reversible encryption – I suspect the former – plain text”

    you’ve got WordPress installed right ? perhaps you could see for yourself ?

    nicely put, _ck_.

  20. Pingback: «leftbraned
  21. He brought up some good points actually. I actually like it when sites send me my username and password. As it’s easy for me to regain access this way – however showing the password with https is kinda bad on their part.

  22. Nice post, Jason.

    I encountered countless similar examples. And as Marc mentioned, when you inform them in a hope for improvements, they don’t admit it. That’s instead of rewarding, or lat least thanking, you for reporting the flaws to them before they possibly become a scandal.

    Something surprised me, though. You said you would wait for SHA2, but SHA2 has been already available for a few years now. Is this a typo or something? I agree with you that SHA1 is a good enough. However, I try to use best when it comes to security. SHA2 for hashing and AES for encryption.

  23. Pingback: gary
  24. I think the Mailman people say it’s excusable because a mailing-list password is a low-priority secret. Still not real brilliant, IMO.

  25. a) So? That’s a lame excuse for bad security practices. Having control of a blog stolen could have serious consequences.

    b) And this makes no sense. There are ways to do bad security that reduce customer interactions, but the way WordPress does it doesn’t actually reduce customer interaction all.

  26. I’m not saying it’s right. I’m trying to explain the rationale behind why WP might not care about this article’s criticisms.

    Sometimes you choose to make things easier to break into in order to make it easier to use.

    WP made it easier for the end user.

  27. > SHA-1 produces a 160-bit hash. That is,
    > every message hashes down to a 160-bit number.

    How long are your passwords? Do they hash DOWN to a 160-bit as Schneier sugggests, or are your passwords hasing UP to a 160-bit number. We’re not hashing documents, we’re hashing 8 to 25 character passwords.

    > Or, a machine that cost $25M-$38M could do 269 calculations in the same 56 hours.

    As someone said – this isn’t a bank, it’s a blogging site. :) I think SHA-1 + salt will do just fine for a blogging site.

  28. No, I personally don’t have WordPress installed – after all – this is the internet. I certainly don’t have to have it installed to use it. This is why I said ‘suspect’.

    My reasons for this suspicion was two-fold:
    1. The password was displayed to me on the web site. Hashes can’t do that.
    2. Why would a site distribute passwords in the clear over SMTP and HTTP and then go through the trouble of encrypting them in the DB.

    I’ve seen a code snippet now and it appears that it’s hashed after the fact. But since the password is displayed after activation, that can only mean it’s hashed after the account is activated. This leaves a window of time where the password is unencrypted in the system.

  29. Hi, I’m one of the folks behind WordPress and WP.com.

    We can display the password to you on the site (and email it to you) because it was just randomly generated and for the duration of that page load we have it in memory.

    After that it’s stored in the DB using phpass, which you can read a bit more about on Ryan’s blog.

    The code that runs WordPress is publicly available, you don’t have to take my word for it you can check it yourself.

  30. Hey Matt, thanks for weighing in on the discussion. Normally I would agree with you. However in this particular situation, I was in fact displayed MY password I entered. Not some randomly generated – change immediately password.

Leave a Reply

Your email address will not be published. Required fields are marked *