How Not to Do Web Site User Registration
appsecstreetfighter.com
appsecstreetfighter.com
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.
This isn't true if the website uses https (since we're talking about sniffing, not man-in-the-middle).
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.
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.
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?
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.
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.
(plus, protecting the user is priority #1.)
Never store passwords in plain text. They are open to a disgruntled employee. It happens frequently enough to just not take a chance.
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).
Unless the attacker obtains the private key for a root certificate, HTTPS remains secure no matter what location it's used from.
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.
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.
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.
There is no perfect scheme, because there are no perfect memories...
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.
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!
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.
Security is very difficult. You can't treat it glibly. Your users deserve more respect than that.
Most web apps (other than banks and people that store credit card data (not process)) are probably fine. right?
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...
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.
Storing the password unhashed (encrypted or plaintext) is NOT a reasonable standard of care.
Also, imagine how many spammers would take over your blog if they could.
Yes it should be https at the least, but aren't you going to go in and change the password immediately anyways?
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.
site:en.wordpress.com "your account is now active"
I don't think SSL is really necessary for a community site like the wordpress one.
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?
// 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);
}