Hacker News new | past | comments | ask | show | jobs | submit login
How Not to Do Web Site User Registration (appsecstreetfighter.com)
68 points by vollmond on May 27, 2009 | hide | past | favorite | 49 comments



Sigh. Everyone has an opinion about website registration and password storage, and most of them have never actually administered a large website.

Was your original signup https? No? Then the hypothetical attacker who is reading all the traffic on your connection already has your password. Would you happily login to your account from the WiFi at Starbucks, or from the public machine at the local library? Yes? Then the hypothetical attacker already has your password.

Emailing passwords to new users is USEFUL. It undoubtedly saves Wordpress hundreds of support requests PER DAY. That is real money saved, and it must be balanced against the insignificant risk of being "hacked" by someone reading your email on the wire.

ANY ability to reset a password via email is insecure. The email is plaintext; it must contain enough information for the recipient to get into his account; therefore, an attacker on the wire can get into the account. It doesn't matter how the password is stored or how the password reset is accomplished, it's equally insecure. There is NO SECURITY DOWNSIDE to emailing a user's password to them vs. having some multi-step reset procedure.

An attacker which can read out the passwords from your database already owns your site.

Finally, complaining about the activation key (which is a hexidecimal hash value) is insane. It's far more secure than any other passwords on the site at all.

Finally finally, I think Wordpress does store passwords as one-way hashes, so most of this guy's argument is moot anyway.


> Was your original signup https? No? Then [...]

Sounds like a good reason to use HTTPS for registration and authentication, as stated in the article.

> Would you happily login to your account from the WiFi at Starbucks

Sure, as long as the site uses HTTPS.

> or from the public machine at the local library?

Never, never, never.

> Emailing passwords to new users is USEFUL [...]

Allowing anybody to login without a password would doubtless save them even more support requests, but that doesn't mean it's a good idea. Sometimes the developer's responsibility to protect a user's information outweighs a desire for lower support costs.

> ANY ability to reset a password via email is insecure. [...]

Not so; additional information, such as user-defined security questions or verification, is usually required before a user is allowed to reset their password. Furthermore, a theoretical weak reset procedure only exposes the weak site. It doesn't expose the user's password.

> An attacker which can read out the passwords from your database already owns your site.

This isn't about protecting your site, it's about protecting users. Many people, despite decades of warnings, use the same password on multiple sites. If your site stores the user's authentication information in a way that can be accessed later, then you are violating the user's security.


> An attacker which can read out the passwords from your database already owns your site.

Never store passwords in plain text. They are open to a disgruntled employee. It happens frequently enough to just not take a chance.


>Sure, as long as the site uses HTTPS.

You really should think again about your logins especially if you are near a college campus and especially if you aren't using firefox (which will pop up with a warning on an https site when you are tunneled through someone else's computer).


Are there truly any major browsers that won't display an error page on bad (spoofed, self-signed, invalid, etc) certificates? A cursory Google search suggests that at least FF, IE, Chrome, and Opera will refuse to load such a page unless the user clicks through.

Unless the attacker obtains the private key for a root certificate, HTTPS remains secure no matter what location it's used from.


thank you for such high signal to noise.

(plus, protecting the user is priority #1.)


It is impossible to store passwords in a one way hash and also email it to a user and show it on a web page at some point in the future. That's the point of a one way hash, it can only be encrypted, not unencrypted. No one should ever be able to see what that original password was -- even people with access to the database.

Lots of peope use the same passwords for multiple sites. If I have access to your WP password and username and other sites you visit, I could hack those too!

I haven't looked at WP's code, but if the blog is accurate, then those passwords must be at best two-way encrypted.


The blog is not accurate. They only send you your password the first time, when you create it. They store a hash, all you can do afterwards is reset it.

http://support.wordpress.com/passwords/


Makes me feel a bit better about WP. They are still storing the passwords temporarily in 2-way, so it's less of a hacking risk for the new account, though potentially a hacking opportunity for other websites used by the same user.

I still can't say I approve of their implementation though. What if someone is looking over your shoulder when you click the link to see your new account has been created and your password is right there for someone watching?


There is NO SECURITY DOWNSIDE to emailing a user's password to them vs. having some multi-step reset procedure.

One downside is that the email can later be found and used by an attacker, whereas the multi-step procedure generally relies on information not present in the directions (such as a birthdate or secret question). An attacker who gains access to the email at a later point (not just intercepted) can gain access to the account without further effort or risk.

Another downside is that exposing the password in plaintext allows the attacker to gain access to other accounts on other systems where the user has used the same password. In contrast, the multi-step approach must be used against every site.

To say that there is 'no downside' is to say that there is no problem with storing passwords in plain text on your server, because if an attacker has gained access to your server they already have access to your accounts. Possibly true, but this ignores the irresponsible and anti-social aspects of exposing a user to further attacks.


"Would you happily login to your account from the WiFi at Starbucks, or from the public machine at the local library? Yes? Then the hypothetical attacker already has your password."

This isn't true if the website uses https (since we're talking about sniffing, not man-in-the-middle).


Ecrypted wireless connections also help. I'm always very cautious about the kind of wireless link I'm using.

You have to be conscious on the internet, that's the moral here. I have stopped using websites that sent me my password in plain text, unless I just don't care about the account. If the developers aren't savvy enough to know how to protect their users, I lose confidence in them.


Wireless encryption only protects your packets until they reach a router. After that, it's just as (in)secure as a wired connection.


Especially if (it turns out) the wifi SSID to which you are connecting does not actually belong to the starbucks (or some indie coffee shop offering wifi) but some black hat in an office in the building with the starbucks.


Generally, that's only reliable if you're using WPA2. There are cracks to all the other popular encryption protocols.


"There is NO SECURITY DOWNSIDE to emailing a user's password to them vs. having some multi-step reset procedure."

That may be true from a site admin's POV, but consider that many people use the same password for everything. Plain text passwords flying through the pipes and then laying about on mail servers is a security risk for the naive user.


> There is NO SECURITY DOWNSIDE to emailing a user's password to them vs. having some multi-step reset procedure.

Yet another downside is that the hacker can continue to access your account indefinitely without you knowing. If they have to reset the password then you'll find out the very next time you go to login.

Despite this I agree that the usability gains from using viewable passwords can surpass the security disadvantages.


I think it is okay to email the user a new randomly generated password. There's not much difference between that and a link the user can click to create a new password. I suggest not putting the username and the password in the same email -- ever -- even if it is randomly generated.

It actually may be better to send a random new password, rather than a link, because then the hacker needs to at least guess something, in this case, the username, so it may be more secure.

For added security, you can make the random password (or the link if you want to do it that way) expire so the user has to be a bit prepared. That reduces the window for someone reading their emails to jump in and steal the account.


Except that if you email a new password anyone can reset someone's password by only knowing the email. It can be a real pain. Imagine being on the customer support side when an unknown third party keeps resetting someone's password.


You don't reset the user's password when he/she requests it via a web form. You send the user an e-mail with a cryptographically secure token (rather, a URL containing the token) that allows them to reset their password. You keep a table of valid tokens and expire them regularly. That will serve the same purpose without causing an inconvenience to the user.


Some people do reset the password when requested via a web form though, that's what I was replying to. For my own projects I do what you suggested.


With the Mantis Bug Tracker, users can request a password reset based on username, but it does not prevent the user from continuing to login via the existing password if the user does not get/click on the password reset link from the email.


I like that idea.


That's more of a DoS attack than a breach of security. You can detect mass password rests and determine if that is happening. However, in practice, I've never really heard of this happening (I'm sure someone will point me to some examples). But again, this is just another sort of DoS attack.


In this case, you introduce the concept of the "secret question and answer." But then sometimes users forget those too.

There is no perfect scheme, because there are no perfect memories...


Perhaps no perfect scheme, but you can do better than provide a "lock someone out of their account if you know their username" button as described above.


What is a better method? I'm not disagreeing with you. I am encouraging you to share better ideas.


A better method is to send a special link to a user who requested to reset their password. After clicking on that link they can change it and log-in. That makes it such that the user is the only one that can trigger the reset.

The worst a third party can do is trigger an email (simply note in the email that if you did not request the email to ignore it and that your account is still safe).

This is a common technique.


Yes but you should make that random password a reset password that starts becoming valid only once used and sends the user directly to a new page where he can change his password


There's no two ways about it. If you don't take reasonable care with your users sensitive data, especially things like passwords, security questions, credit card information, etc. then you are an completely incompetent unprofessional hack and also a creep, a jerk, and a generally miserable person to boot.

That means you don't store passwords in an unhashed format (plaintext or encrypted). You don't store credit cards at all unless you've can't find any other design options. And if you do store them, you take great pains to meet or exceed reasonable standards (like PCI) for storing them safely and properly.

This is vastly more important than what language or framework you use. Vastly more important than whether you use CCS or tables. Vastly more important than whether you use a SQL database or a hip new RESTFUL key-value store.

This is about trust. This is about integrity. This is about professionalism. Are you trustworthy? Are you a professional? Then do the right thing damn it!


For reference I give you: Reddit and their password losing debacle. (http://blog.moertel.com/articles/2006/12/15/never-store-pass...)


Honestly, this is a classic usability vs security question. All the other suggestions (other than the over the top I'm flipping out because this is so insecure stuff) are ok, except for #5.

Are you seriously telling me that there are hackers out there waiting to break into a blog that you might never edit? No. But, if you do forget your password, and they sent it to you in an email you can go back and look for it. Most people do.

Web app security is a big deal, but not if what you're securing isn't worth the usability hit.

EDIT: I wasn't talking about storing plain-text passwords in the db, but more about sending it via email to the user before you encrypt it and store it in the db.


In this example, it was "just a blog" but there are serious sites that will email you your plain text password too. Verio stores two way encrypted passwords and domains are important to some people and they do get stolen and they are valuable, so this is a serious issue.

Security is very difficult. You can't treat it glibly. Your users deserve more respect than that.


Sure, anything that has sensitive information about you needs to treat security as a priority.

Most web apps (other than banks and people that store credit card data (not process)) are probably fine. right?


That would be right if people didn't use the same email and password as their paypal account everywhere... But since a lot of people do, getting the security right on your web app is important.


aditya, from a developer perspective, I cannot think of any reason to ever store recoverable passwords in a database. It's just too easy to do a one way hash.

Okay, there is only one reason, if you are building a system that allows the storage of multiple accounts and passwords that are "re-used" like in some browsers' auto-complete feature. Then the concern is security of the local machine and if you use that technology, you're increasing your personal risk.

In the scenario I mention there, it is absolutely imperative to use an advanced two-way encryption algorithm. In that case, the hacker will need to compromise the database and the code, which should be obfuscated as well so the decryption keys are more difficult to discover.

There are some hackers who will always be able to hack you and some that will never be able to hack you. It's a probability game and you want to reduce the probability as much as possible that anyone will get in...


Really?

I have a dozen of reasons to have the passwords recoverable - when the angry big customer is having problems with the application and you need to access his account to reproduce the issue being on a level 4 support, you really want to have the password straight away, and there are many other scenarios, like when you need to test something on a production server with some real data but cannot get access to any accounts as it takes years in a big corp to have something done.

So from a developers perspective - as opposed to business/marketing side - i cannot think of any reason to ever store unrecoverable passwords in a database. Makes it easier to implement, easier to restore, easier to maintain, easier to test.


No, it's not fine. As the commenter above you said, your users deserve more respect than that. Most users, particularly unsophisticated users, re-use the same passwords across most or all of their accounts. It's a bad practice, but they do this because (amount other reaons) they expect that the people who run the websites they use would have the minimum respect and courtesy to treat the passwords with a reasonable standard of care.

Storing the password unhashed (encrypted or plaintext) is NOT a reasonable standard of care.


You'd be surprised. Remember the issue that happened with peoples' twitter accounts being broken into?

Also, imagine how many spammers would take over your blog if they could.


I highly doubt Wordpress.com is storing the passwords in a reversible encryption, or in plain text. It seems to me that when the user hits that page, the password is generated and displayed.

Yes it should be https at the least, but aren't you going to go in and change the password immediately anyways?


If you look at the actual WP create account page here: http://en.wordpress.com/signup/

You'll see that there is a box for your password and a confirmation of the password, so that leads me to believe that they are actually sending the user the password they created the account with, rather than a randomly generated one. Otherwise, why have the input fields there at all?

Therefore, they must be storing either plain text or two-way encryption.


Which also suggests that these are passwords that most users use for other online accounts...


I agree, the main issue here is that they're not using SSL during these steps, and the second is that they don't recommend changing your password from the generated default.


as pointed out in the article comments:

site:en.wordpress.com "your account is now active"


The whole thing reminds me of that old joke when you encrypt/cypher/code the beast, but the user will still put it on sticknote on his monitor.


Am I only one not too concerned about the Chinese hackers stealing my WordPress support forums password then posting WordPress support questions using my login credentials? It's almost a nuisance that a support forum requires you to create a user account at all!


Wordpress defiantly encrypt there passwords in some unreversable format using a salt.

I don't think SSL is really necessary for a community site like the wordpress one.


Ugh. I wish there was some kind of voting undo. (I accidentally upvoted you.)

First: I assume you mean that Wordpress _definitely_ encrypts their passwords, not defiantly.

Second: What is your proof they they are hashing passwords, salted or not?


From the source code of Wordpress MU:

   // If the stored hash is longer than an MD5, presume the
        // new style phpass portable hash.
        if ( empty($wp_hasher) ) {
                require_once( ABSPATH . 'wp-includes/class-phpass.php');
                // By default, use the portable hash from phpass
                $wp_hasher = new PasswordHash(8, TRUE);
        }




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: